понедельник, 29 сентября 2014 г.

Удаленная ветка реестра пользователя / access remote registry user

Доброго времени суток

Работа с удаленным реестром на первый взгляд кажется простой, пока дело не касается личных параметров пользователя.

Ветка "HKEY_LOCAL_MACHINE" нам всегда доступна удаленно, так как она содержит общие параметры для всех пользователей удаленной машины
Но ветка "HKEY_CURRENT_USER" будет скрыта, так как для каждого пользователя она своя.
В место неё нам предлагаю "HKEY_USERS" которая содержит все ветки "HKEY_CURRENT_USER" всех пользователей когда либо заходивших в удаленную систему
Сложность заключается в том, что все ветки в "HKEY_USERS" именованны SID(ами) пользователей.

Рассмотрим пример получения/записи параметров "HKEY_CURRENT_USER" ветки пользователя который работает на удаленной машине используя PShell.
В качестве примера будет приведен пример изменение таймаута заставки экрана.

$PC = "Host1"

#Узнаем кто залогинен на машине
$User = (Get-WmiObject Win32_ComputerSystem -Computer $PC).username

#Получаем SID залогиненного пользователя из AD
$objUser = New-Object System.Security.Principal.NTAccount($User)
$UserSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$UserSID = $UserSID.Value

#Задаем путь к удаенной ветке с сидом
$key =  $UserSID + "\Control Panel\Desktop\"

#Задаем ссылку на системуную процедуру подключения к реестру
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::Users,$PC)

#Вызываем подключение к удаленному реестру по указанному ранее пути
$key = $reg.OpenSubkey($key,$True)


#Получим параметр интервала заставки пользователя
$key.GetValue("ScreenSaveTimeOut")

#зададим его для удаленного пользователя(занчение в секундах)
$key.SetValue("ScreenSaveTimeOut","60")



PS если вы не видите результата в системе, перезапустите её

Поиск устаревших сертификатов / Search older certificates

# Список опрашиваемых серверов, с разделителем #
$servers = "Host1#Host2#Host3"
# Оставшееся количество дней ликвидности сертификата
$Exp_day = 20
################################
# Установим дату окончания
$Exp_day = (Get-Date).AddDays($Exp_day)
################################
# Преобразуем строку в массив используя разделитель
$servers = $servers -split "#"


foreach ($Server in $Servers) {
write-host "Old certificates to" $Server

$ro=[System.Security.Cryptography.X509Certificates.OpenFlags]"ReadOnly"
$lm=[System.Security.Cryptography.X509Certificates.StoreLocation]"LocalMachine"

$store=new-object System.Security.Cryptography.X509Certificates.X509Store("\\$Server\My",$lm)
$store.Open($ro)

$store.certificates |  %{$_ | Select Issuer,subject, NotAfter, @{Label="ExpiresIn"; Expression={($_.NotAfter - (Get-Date)).Days}}} | where {$_.ExpiresIn -ge 0} | where {$_.NotAfter -le $Exp_day}
}

вторник, 23 сентября 2014 г.

Выполнение удаленной команды от пользователя / remore run app Interactive

Доброго времени суток
Настал тот момент, когда вам необходимо удаленно выполнять команды на ПК пользователей, как это сделать используй PowerShell и WMI я опишу ниже в 2-х частях

1 часть
Удаленный запуск приложения:

 #Вводим имя компьютера
$PC = 'test-pc'
#Вводим команду
$command = 'c:\saplogon.bat'

#Формируем строку для WMI

$WMI_Path = "\\" +  $PC + "\root\cimv2:Win32_Process"
#Запускаем удаленную команду

([wmiclass]$WMI_Path).create($command)

Есть важное ограничение, все выполняемые команды и приложения должны располагаться локально на машине.По этому "saplogon.bat" в данном примере я заранее скопировал на удаленную машину

2 часть
Запуск приложения в интерактивном режиме для пользователя
Как вы можете обратить внимание, в первой части все запущенные приложения будут выполнены от вашей учетной записи, это не даст пользователю никак использовать запущенное приложение и даже увидеть его формы.

#Вводим имя компьютера
$PC = 'test-pc'
#Вводим команду
$TaskR = 'c:\saplogon.bat'
#Формируем строку для WMI$WMI_Path = "\\" +  $PC + "\root\cimv2:Win32_Process"

далее нам необходимо, используя  "SCHTASKS", создать запланированное задание. Используя предыдущий метод получения логина пользователя на компьютере и выполнения удаленных команд из первой части создадим его.
 
#Получаем WMI объект удаленной системы с информацией о системе
$WMI_Object = Get-WmiObject Win32_ComputerSystem –Computer $PC

#сформируем команду для создания задачи, подробнее о SCHTASKS тут
#в данной команде: создать задание от имени пользователя, остальные условия не важны, так #как запуск задания мы произведем самостоятельно
$command = "SCHTASKS /Create /SC MONTHLY /MO first /D SUN /TN REMOTE_RUN /TR $TaskR /RU " + $WMI_Object.UserName


#Выполним команду по созданию задания
([wmiclass]$WMI_Path).create($command)

#Теперь нам необходимо запустить задание
$command = "SCHTASKS /Run /TN REMOTE_RUN"
([wmiclass]$WMI_Path).create($command)
#советую подождать немного
sleep 5

#и конечно прибрать за собой, удалив данное задание
$command = "SCHTASKS /delete /TN REMOTE_RUN /F"
([wmiclass]$WMI_Path).create($command)

понедельник, 22 сентября 2014 г.

Парсинг объектов Active Directory / get object Active Directory

Парсинг объектов Active Directory по заданный атрибутам используя PowerShell


#Задаем настройки поиска, данный блок задает их автоматически из вашего домена
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $dom.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root


#Задаем параметры поиска

$search.PageSize = 10
#Максимальное кол-во элементов для поиска

$search.Filter = "(&(objectClass=user)(!title=*инж*)(mail=test*))"
#Фильтр поиска по заданным атрибутам, рассмотрим его детально:

#что бы объединить несколько условий нам необходимо поставить знак "&" в начале
#objectClass=user или computer указывает на то какой класс объектов мы ищем
 #!title=*инж* знак восклицания указывает на обратное,
#а это значит атрибут title не должен содержат в себе слова "Инж"
 #mail=test* значит в поле mail в начале должно присутствовать слово "test"
$search.FindAll()

#Запускаем поиск




 Немного обработки для дальнейшей работы:
 ($search.FindAll() | %{$_.path})  - оставить только ldap путь к обьекту

Кто работает за компьютером / get user login remote

Доброго времени суток.
У каждого администратора наступает тот момент когда необходимо более эффективно контролировать свой парк и своих пользователей, а для этого хорошо бы знать кто за каким компьютером работает. В этом нам поможет PowerShell и WMI.

#Вводим имя компьютера
$PC = "test-pc"

#Получаем WMI объект удаленной системы с информацией о системе
$WMI_Object = Get-WmiObject Win32_ComputerSystem –Computer $PC
#Получаем из всей информации имя пользователя
$UserName = $WMI_Object.UserName


#формируем логин убрав домен и слэш
$login = $UserName -replace "^.+\\"
$login

 Вот таким коротким способом можно узнать логин, осталось только прикрутить список компьютеров и вперед!

Сокращение в одну строку:
((Get-WmiObject Win32_ComputerSystem -Computer $PC).UserName -replace "^.+\\")

Лично я решил разместить информацию о пользователе прямо в AD в каждой записи компьютера, задав атрибут "managedBy" и у компьютеров появились кабинеты и адрес