Последние записи.

Установка патчей через логон-скрипты

Возвращаясь к вопросу о необходимости установки обновлений на рабочие станции допустим следующие сценарии:

  1. Патч только вышел
  2. Сервер обновлений не сконфигурирован или отсутствует
  3. Патч вышел давно, но никто его не потрудился одобрить на сервере обновлений.

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

В данном случае поможет простой скрипт который приведен ниже.

Итак. В данном примере рассматриваем установку патча KB958644.
Дано:

  1. Рабочие станции под управлением Windows XP на двух языках EN и RU
  2. Серверы Windows 2003 только на английском языке.

В переменной strHotfix задается имя патча.
В переменной strPatchPath путь до папки где лежат нужные патчи.
В переменной strWinXpEN - имя файла для Windows XP EN
В переменной strWinXpRU – имя файла для Windows XP RU
В переменной strWinServer2003 – имя файла для серверной версии

Создаем скрипт, помещаем его на SYSVOL, например в папку Scripts и создаем необходимые настройки помещая этот скрипт в секцию автологина для компьютера.

On Error Resume Next

strComputer = "."
strHotfix = "KB958644"
strPatchPath = "SRV-01\deploy\System\Patchs\KB958644"

strWinXpEN = "\WindowsXP-KB958644-x86-ENU.exe"
strWinXpRU = "\WindowsXP-KB958644-x86-RUS.exe"
strWinServer2003 = "\WindowsServer2003-KB958644-x86-ENU.exe"
strSwitches = " /u /z"

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

For Each objOperatingSystem in colOperatingSystems
If (InStr(1,objOperatingSystem.Caption, "XP", 1)) Then
If isinstalled(strcomputer, strHotfix) Then
‘Wscript.Echo "Patch is already installed!"
ElseIF (objOperatingSystem.OSLanguage = 1033) Then
strCmd = chr(34) & "\\" & strPatchPath & strWinXPEN & Chr(34) & strSwitches
‘Wscript.Echo "Patch (EN) is not installed! Press OK to continue installing."
installPatch strCmd
ElseIF (objOperatingSystem.OSLanguage = 1049) Then
strCmd = chr(34) & "\\" & strPatchPath & strWinXPRU & Chr(34) & strSwitches
‘Wscript.Echo "Patch (RU) is not installed! Press OK to continue installing."
installPatch strCmd
End If
ElseIf (InStr(1,objOperatingSystem.Caption, "2003", 1)) Then
If isinstalled(strcomputer, strHotfix) Then
‘Wscript.Echo "Patch is already installed!"
Else
strCmd = chr(34) & "\\" & strPatchPath & strWinServer2003 & Chr(34) & strSwitches
‘MsgBox "Patch is not installed! Press OK to continue installing."
installPatch strCmd
End If
Else
‘Wscript.Echo "Unknown OS type"
End If
Next

Function isInstalled(strComputer,srtHotfix)
isinstalled = false
Set objWMI = GetObject("WinMGMTS://" & strComputer & "/Root/CIMv2")
strWQL = "SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID = ‘" & strHotfix & "’"
Set colResults = objWMI.ExecQuery(strWQL)
For Each objItem In colResults
isinstalled = true
Next
If isinstalled = true then isinstalled = true
If IsObject(objItem) Then Set objItem = Nothing
If IsObject(objWMI) Then Set objWMI = Nothing
End Function

Function installPatch (strCmd)
Set oShell = CreateObject("WScript.Shell")
‘WScript.echo strCmd
Command = "cmd.exe /c " & strCmd
RetCode = oShell.Run(Command,1,True)
‘Wscript.Echo "Finished. return code- " & RetCode
End Function

wscript.quit(0)

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

Сохранение фотографий пользователей в AD

Powershell Logo

Наткнулся на статью о сохранении фотографий пользователей в GAL.

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

Для Exchange 2010 существует коммандлет Import-RecipientDataProperty который предназначен для загрузки небольших фотографий до 10 кб с рекомендованным разрешением 96 на 96 точек (при большом желании фотография сжимается до 2-3 кб).

Если заглянуть поглубже в Active Directory то там существует атрибут Picture (по классификации ldapDisplayName: thumbnailPhoto) для размещения фотографий. Его мы и будем мучать в приведенном ниже скрипте.

При неимении установленного Exchange 2010, например есть Exchange 2007 и клиенты к нему Outlook 2010, вы можете автоматизировать процесс загрузки фотографий следующим скриптом.

$folder = "D:\ADPhotos\"

$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $domain.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root
$search.Filter = "(&(objectCategory=Person)(objectClass=User))"

$search.FindAll() | foreach {
$user = [adsi]$_.path
$accountName = $user.psbase.Properties["samaccountname"]
$jpgfile = "$folder$accountName.bmp"
if(!(test-path $jpgfile)){
write-host "User $($accountName) – image not found."
} else {
[byte[]]$jpg = Get-Content $jpgfile -encoding byte
$user.put("thumbnailPhoto",  $jpg)
$user.setinfo()
Write-Host "User $($accountName) – updated."
}
}

В переменной $folder задается папка откуда берутся фотографии заданные в формате
логин_пользователя.bmp

Если необходимо поменять фильтр для поиска, в данном примере поиск идет для всех учетных записей пользователей, поменяйте строку
$search.Filter = «(&(objectCategory=Person)(objectClass=User))»
на необходимую.

Старый знакомый – Win32/Conficker.C

редкая гадостьСтарая как мир фраза оказалась необычайно актуальной.

В очередной раз пришлось бороться со старым знакомым…

В очередной раз с переменным успехом т.к. силы явно не равны, но в итоге сопротивление червя-интеллектуала (на контроллеры собака… совался редко, главными объектами были выбраны сервера приложений, старался портить как можно меньше, но блокировал учетные записи до 150 штук за 10 минут) было сломлено и кривая потянувшаяся вверх в первый день инцидента неумолимо стала стремиться к отметке ноль.

Одна из методик борьбы с червем conficker является установка патча KB958644. Не стоит забывать что еще нужны

  • MS08-068 – KB957097
  • MS09-001 – KB958687

Ниже приведен скрипт для работы которого нужно подготовить файл Hostlist.txt со списком необходимых хостов.

Сразу после запуска скрипта производит запрос учетных данных под которыми будет производится работа, далее в зависимости от результатов работы формируется два файла:

  1. Offline.txt – сюда заносятся хосты которые выключены.
  2. Missing-KB958644.txt – в этот файл помещается список проблемных хостов на которых отсутствует нужный патч.
function Get-HotFix {
param (
[string[]]$ComputerName = ".",
[string]$Id = "",
[string]$Description = "",
$credential
)
trap {$false; continue}

if ((gwmi Win32_PingStatus -Filter "Address=’$ComputerName’").StatusCode -eq 0) {
if ($id -ne "" -and $Description -eq "") {
$id = $id.Replace("*","%")
$filter = "hotfixid LIKE ‘$id’"
} elseif ($id -eq "" -and $Description -ne "") {
$Description = $Description.Replace("*","%")
$filter = "description LIKE ‘$Description’"
} elseif ($id -ne "" -and $Description -ne "") {
Write-Host "WARNING: Use Id or Description parameter." -foregroundcolor yellow ;break
} else {
$filter = ""
}
if ($credential -eq $null) {
$HotFixes = get-wmiobject Win32_QuickFixEngineering -computerName $ComputerName -filter $filter | where-object {$_.hotfixid -ne "file 1"}
} else {
$HotFixes = get-wmiobject Win32_QuickFixEngineering -computerName $ComputerName -filter $filter -credential  $credential | where-object {$_.hotfixid -ne "file 1"}
}
$HotFixes
} else {
Write-Host "$($_) – Offline."
add-content $_ -path Offline.txt
}
}

$a = get-content Hostlist.txt
$credential = Get-Credential DOMAIN\User

$a | foreach { if (!(get-hotfix -id KB958644 -computername $_ -credential $credential)) {
Write-Host "$($_) – Missing KB958644."
add-content $_ -path Missing-KB958644.txt
} else {
Write-Host "$($_) – OK."
}
}

PS. к слову сказать приведенный скрипт с легкостью найдет все что его попросите, нужно только оперировать параметрами вызова процедуры

  • $Id – название патча
  • $Description – его описание

Windows 2008 аудит журналов доступа

Powershell Logo
В предыдущей заметке рассматривался аудит входов для Windows 2003. В ходе небольшого обсуждения скрипт представленный ранее был модернизирован и теперь его можно использовать для работы с Windows 2008.

$log = Get-EventLog  security | ?{$_.eventid -eq 4624 -or $_.eventid -eq 4634 -and $_.message -like "*Logon Type:`t`t`t2*" -or $_.message -like "*Logon Type:`t`t`t10*" -and  $_.TimeGenerated -gt (Get-date).AddHours(-1)}

$event = New-Object System.Management.Automation.PSObject
$event | Add-Member NoteProperty Event ($null)
$event | Add-Member NoteProperty Code ($null)
$event | Add-Member NoteProperty Time ($null)
$event | Add-Member NoteProperty UserName ($null)
$event | Add-Member NoteProperty Address ($null)

$log | %{
$event.Event = $_.eventid
$event.Code = ($message | ?{$_ -like "*Logon Type:*"} | %{$_ -replace "^.+`t *"})
$event.time = $_.TimeGenerated; $message = $_.message.split("`n") | %{$_.trimstart()} | %{$_.trimend()}
$user=($message | ?{$_ -like "*Account Name:*"} | %{$_ -replace "^Account Name:`t`t *"})
$event.UserName = $user[1]
$event.Address = ($message | ?{$_ -like "Source Network Address:*"} | %{$_ -replace "^.+`t *"})
$event
}

Старый добрый NTBackup

Микрозаметка о том каким образом создавать бэкапы с именем файла равным текущей дате.

В приведенном примере имя файла будет выглядеть следующим образом – день-месяц-год.bkf
В файле D:\Backup\CustomSelection.bks должен быть определен список того что необходимо копировать, например:

SystemState
C:\Users

Собственно и сам скрипт.

@echo off
FOR /F "tokens=*" %%i in ('echo %DATE%') do SET Today=%%i
FOR /F "tokens=1-3 delims=/." %%A IN ("%Today%" ) DO (
SET Month=%%A
SET Day=%%B
SET Year=%%C
)
C:\WINDOWS\system32\ntbackup.exe  backup "@D:\Backup\CustomSelection.bks" /v:yes /r:no /rs:no /hc:off /m normal  /j  "CustomBackupJob" /l:s /f "D:\Backup\Custom\%day%-%month%-%year%.bkf"