Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Данный сценарий предназначен для упрощения задач администрирования Windows Server Update Services (WSUS)
- .Description
- Сценарий позволяет импортировать и экспортировать одобрения обновлений WSUS, а также переносить одобрения с тестовых групп на "боевые".
- Сценарий имеет два режима работы: в режиме консольного приложения и в режиме графического приложения. По умолчанию (если не задан ни один параметр командной строки) сценарий запускается в графическом режиме. В иных случаях - в режиме командной строки
- .Parameter DoImportFromFile
- Путь к файлу, из которого нужно импортировать одобрения обновлений. Если этот параметр не задан (или указан несуществующий / некорректный) путь, импорт настроек не происходит.
- .Parameter DoExportToFile
- Путь к файлу выгрузки (экспорта) одобрений из WSUS. Если этот параметр не указан (или указан некорректный / пустой путь), экспорт одобрений в файл не выполняется.
- .Parameter ServersCopyTestApprovals
- Делать перенос одобрений с группы "gWSUS_Srv_test" на группу "gWSUS_Srv_prod"
- .Parameter WorkstationsCopyTestApprovals
- Делать перенос одобрений с группы "gWSUS_Wks_test" на группу "gWSUS_Wks_prod"
- .Parameter PathToLog
- Переназначает путь к лог-файлу. По-умолчанию, если не указан, лог пишется в TEMP-директорую, определённую системой.
- .EXAMPLE
- .\wsus_admin_tool -DoImportFromFile c:\vms_updates.waf
- Данная команда запустит импорт одобрений WSUS из файла c:\vms_updates.waf
- .EXAMPLE
- .\wsus_admin_tool -DoExportToFile c:\2mpk\all\WSUS\today.waf
- Данная команда запустит экспорт данных об одобрениях в файл c:\2mpk\all\WSUS\today.waf
- .EXAMPLE
- .\wsus_admin_tool -DoImportFromFile c:\vms_updates.waf -ServersCopyTestApprovals
- Данная команда запустит импорт одобрений WSUS из файла c:\vms_updates.waf, после чего одобрит все обновления, одобренные на группу gWSUS_Srv_Test, на группу gWSUS_Srv_Prod
- .EXAMPLE
- .\wsus_admin_tool -ServersCopyTestApprovals -WorkstationsCopyTestApprovals
- Данная команда скопирует одобрения с группы gWSUS_Srv_Test на группу gWSUS_Srv_Prod, а с группы gWSUS_Wks_Test на группу gWSUS_Wks_Prod
- .LINK
- http://wiki.mp.local/Надеюсь_кто-нибудь_напишет_статью
- #>
- param ([STRING]$DoImportFromFile="", [STRING]$DoExportToFile = "",
- [System.Management.Automation.SwitchParameter]$ServersCopyTestApprovals=$false,
- [System.Management.Automation.SwitchParameter]$WorkstationsCopyTestApprovals=$false,
- [STRING]$PathToLog="")
- $SCRIPT_VERSION_NUMBER = "0.0041"
- $SCRIPT_NAME_STRING = "Скрипт для WSUS v."
- $STATUS_SCRIPT_ENDED = "Работа сценария завершена"
- $REGISTRY_HKCU_STORE_PATHES_KEY = "HKEY_CURRENT_USER\Software\PowershellWSUSAdminTool\"
- $REGISTRY_STORE_INPUT_FILE_VALUE = "InputFile"
- $REGISTRY_STORE_OUTPUT_FILE_VALUE = "OutPutDir"
- $FILESYSTEM_OBJECT_TYPE_FOLDER = "Folder"
- $FILESYSTEM_OBJECT_TYPE_FILE = "File"
- $ERROR_THERE_IS_AN_ERROR = "Ошибка!"
- $SCRIPT_LOG_FILE_NAME = "WSUS_Admin_tool.log"
- $SCRIPT_RUN_MODE_GUI = "Graphic"
- $SCRIPT_RUN_MODE_CLI = "CommandLine"
- $WSUS_GROUP_NAME_SERVERS_TEST = "gWSUS_srv_test"
- $WSUS_GROUP_NAME_SERVERS_PROD = "gWSUS_srv_prod"
- $WSUS_GROUP_NAME_WORKSTATIONS_TEST = "gWSUS_wks_test"
- $WSUS_GROUP_NAME_WORKSTATIONS_PROD = "gWSUS_wks_prod"
- $WSUS_GROUPS_TO_EXPORT = ($WSUS_GROUP_NAME_WORKSTATIONS_TEST,$WSUS_GROUP_NAME_SERVERS_TEST)
- $XML_TYPE_COMMENT = "Comment"
- $DEFAULT_STATUS_BAR_TEXT = "Задайте нужные параметры и нажмите кнопку `"Выполнить`""
- $SYSTEM_DEFAULT_SHOW_PROGRESS_STEP = 10
- $SYSTEM_DEFAULT_SLEEP_TIME = 10
- #Возвращает экземпляр объекта - сервера WSUS
- Function Get-WsusServerInstance()
- {
- $WSUSServer = $WSUS
- #Получаем ссылку на текущий экземпляр сервера WSUS.
- if ($WSUSServer -eq $null)
- {
- $WSUSServer =[Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer();
- }
- Return $WSUSServer
- }
- #Возвращает объект-группу WSUS по её имени.
- Function Get-WsusGroupByName([STRING]$Name)
- {
- $wsus = $null
- $wsus = Get-WsusServerInstance
- $Groups = $wsus.GetComputerTargetGroups()
- Foreach ($Group in $Groups)
- {
- if ($Group.Name -eq $Name)
- {
- Return $Group
- }
- }
- Return $null
- }
- #Возвращает массив обновлений, одобренных для заданной группы
- Function Get-UpdatesApprovedToGroup([STRING]$GroupName)
- {
- $ApprovedUpdates = @()
- $wsus = Get-WsusServerInstance
- $Group = Get-WsusGroupByName -Name $GroupName
- $UpdateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope;
- #$UpdateScope.UpdateApprovalActions = `
- # [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::Install #-bor `
- #[Microsoft.UpdateServices.Administration.UpdateApprovalActions]::Uninstall
- Change-StatusbarText -Text "Querying updates info from WSUS server..."
- $WsusUpdates = $wsus.GetUpdates()
- $TotalWsusUpdates = $WsusUpdates.Count
- $i = 0
- foreach ($Update in $WsusUpdates)
- {
- $i++
- [STRING]$UpdateKB = $Update.KnowledgebaseArticles
- Show-Progress -CurrentItem $i -Step $SYSTEM_DEFAULT_SHOW_PROGRESS_STEP -Template "Gathering approvals for update. Last porcessed is KB$UpdateKB" -TotalCount $TotalWsusUpdates
- #Проверяем, было ли одобрено текущее обновление на нужную нам группу
- $CurrentApprovals = $update.GetUpdateApprovals($group)
- if ($CurrentApprovals.Count -gt 0)
- {
- #$Added = $false
- foreach ($Approval in $CurrentApprovals)
- {
- #if (($Approval.Action -ne [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::NotApproved )`
- # -and ($Added -eq $false))
- #{
- #Создаем объект, инкапсулирующий свойства обновления и его подтверждения.
- $Record = New-Object Object
- Add-Member -InputObject $Record -MemberType NoteProperty -Value $Update -Name "objUpdate" | Out-Null
- Add-Member -InputObject $Record -MemberType NoteProperty -Value $Approval -Name "objApproval" | Out-Null
- $ApprovedUpdates = $ApprovedUpdates + $Record
- # $Added = $true
- #}
- }
- }
- }
- Return $ApprovedUpdates
- }
- #Экспортирует одобрения (для заданных групп) обновлений в файлы.
- #Тут можно было бы обойтись Export-Clixml, но, во первых, это увеличит размер файла
- #экспорта во много раз, во-вторых, не позволит гибко управлять структурой XML-я.
- Function Export-Approvals ([STRING]$FilePath,[ARRAY]$ApprovedGroupsNames)
- {
- $XML = New-Object XML
- $XMLGroupsNode = $XML.CreateElement("Groups")
- $XML.AppendChild($XMLGroupsNode) | Out-Null
- Foreach ($Group in $ApprovedGroupsNames)
- {
- Change-StatusbarText -Text "Getting updates info for WSUS group: $Group"
- $XMLCurrentGroupNode = $XML.CreateElement("$Group")
- $XML.SelectSingleNode("//Groups").AppendChild($XMLCurrentGroupNode)
- #Получаем обновления, одобренные для данной группы
- $ApprovedUpdates = $null
- $ApprovedUpdates = Get-UpdatesApprovedToGroup -GroupName $Group
- if ($ApprovedUpdates -ne $null)
- {
- $TotalUpdates = $ApprovedUpdates.Count
- $i = 0
- #Правим результирующую XML-ку
- Foreach ($Update in $ApprovedUpdates)
- {
- $i++
- [STRING]$UpdateKB = $Update.objUpdate.KnowledgebaseArticles
- #Write-Status -Message $("Exporting update $i of $TotalUpdates" + ": KB$UpdateKB")
- Show-Progress -CurrentItem $i -Template "Exporting updates approvals. Last processed is KB$UpdateKB" -Step 10 -TotalCount $TotalUpdates
- #Создаем XML-элемент для текущего обновления внутри текущей группы
- $XMLUpdateNode = $XML.CreateElement("Update")
- #$XML.SelectSingleNode("//Groups/$Group").AppendChild($XMLUpdateNode)
- #Добавляем к узлу обновления реальные свойства обновления
- #Продукт, для которого предназначено обновление
- $XMLUpdateProduct = $XML.CreateElement("UpdateProduct")
- $XMLUpdateProduct.InnerText = $Update.objUpdate.ProductTitles
- $XMLUpdateNode.AppendChild($XMLUpdateProduct)
- #Номер KB
- $XMLUpdateKB = $XML.CreateElement("UpdateKB")
- $XMLUpdateKB.InnerText = $UpdateKB
- $XMLUpdateNode.AppendChild($XMLUpdateKB)
- #Описание обновления
- $XMLUpdateDescription = $XML.CreateElement("UpdateDescription")
- $XMLUpdateDescription.InnerText = $Update.objUpdate.Description
- $XMLUpdateNode.AppendChild($XMLUpdateDescription)
- #ID обновления
- $XMLUpadteID = $XML.CreateElement("UpdateID")
- $XMLUpadteID.InnerText = $Update.objUpdate.Id.UpdateId
- $XMLUpdateNode.AppendChild($XMLUpadteID)
- #Признак отмененного обновления
- $XMLUpdateIsDeclined = $XML.CreateElement("UpdateIsDeclined")
- $XMLUpdateIsDeclined.InnerText = $Update.objUpdate.IsDeclined
- $XMLUpdateNode.AppendChild($XMLUpdateIsDeclined)
- #Признак необязательного обновления
- $XMLUpdateApprovalIsOptional = $XML.CreateElement("UpdateApprovalIsOptional")
- $XMLUpdateApprovalIsOptional.InnerText = $Update.objApproval.IsOptional
- $XMLUpdateNode.AppendChild($XMLUpdateApprovalIsOptional)
- #Дедлайн обновления
- $XMLUpdateApprovalDeadLine = $XML.CreateElement("UpdateApprovalDeadLine")
- $XMLUpdateApprovalDeadLine.InnerText = $Update.objApproval.DeadLine
- $XMLUpdateNode.AppendChild($XMLUpdateApprovalDeadLine)
- #Действие, заданное для данного обновления
- $XMLUpdateApprovalAction = $XML.CreateElement("UpdateApprovalAction")
- $XMLUpdateApprovalAction.InnerText = $Update.objApproval.Action
- $XMLUpdateNode.AppendChild($XMLUpdateApprovalAction)
- $XML.SelectSingleNode("//Groups/$Group").AppendChild($XMLUpdateNode)
- }
- }
- Write-Status -Message "Export finished for group: $Group"
- Change-StatusbarText -Text "Export finished for group: $Group"
- }
- Write-Status -Message "Saving export file..."
- Change-StatusbarText -Text "Saving export file..."
- $XML.Save($FilePath) | Out-Null
- Write-Status -Message "Export file saved."
- Change-StatusbarText -Text "Export file saved."
- }
- #
- #Принимает путь к XML-Документу, возращает объект, представляющий этот XML-файл
- Function Get-XmlFile([String]$FilePath)
- {
- If ((Test-Path $FilePath) -and ($FilePath -ne ""))
- {
- $xml = [xml](get-content $FilePath)
- trap
- {
- Throw "Invalid XML file. Check your configuration and spelling."
- }
- }
- else
- {
- Throw "XML-File was not found."
- }
- Return $xml
- }
- #Возвращает значение узла XML
- #Написана для того, чтобы корректно ловить исключения именно в этой функции.
- Function Get-XmlValue ($XML)
- {
- $Res = $xml
- if ($Res -eq $null)
- {
- throw "Invalid XML: there is no needed attribute"
- } else
- {
- return $Res
- }
- }
- #Проверяет валидность XML-файла на основе схемы XSD.
- #Принимает пути к XML и XSD, возвращает $true, если
- #файл валидный и false иначе.
- Function Validate-Xml([STRING]$XMLpath, [STRING]$XmlSchema)
- {
- if ((Test-Path $XmlSchema) -and (Test-Path $XMLpath))
- {
- $readerSettings = New-Object -TypeName System.Xml.XmlReaderSettings
- $readerSettings.ValidationType = [System.Xml.ValidationType]::Schema
- $readerSettings.ValidationFlags = [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessInlineSchema -bor [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation -bor [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings
- $res = $readerSettings.Schemas.Add($Namespace, $XmlSchema)
- $readerSettings.add_ValidationEventHandler(
- {
- $failureMessages = $failureMessages + [System.Environment]::NewLine + $XMLpath + " - " + $_.Message
- $failCount = $failCount + 1
- });
- $reader = [System.Xml.XmlReader]::Create($XMLpath, $readerSettings)
- while ($reader.Read())
- {
- }
- if ($failCount -eq $null)
- {
- $res = $true
- }
- else
- {
- Write-Status -Message "Ошибка в конфигурационном файле скрипта."
- Write-Status -Message $failureMessages
- $res = $false
- }
- }
- else
- {
- $res = $false
- }
- return $Res
- }
- #Импортирует одобрения обновлений из файла
- Function Import-Approvals([STRING]$FilePath)
- {
- Start-WSUSSync | Out-Null
- $WSUS = Get-WsusServerInstance
- $XML = Get-XmlFile -FilePath $FilePath
- $Groups = Get-XmlValue $XML.Groups
- $Groups = $Groups.ChildNodes
- Foreach ($Group in $Groups)
- {
- if ($Group.get_NodeType() -ne $XML_TYPE_COMMENT)
- {
- $GroupName = Get-XMLValue -XML $Group.Name
- Write-Status -Message "Importing updates for WSUS group: $GroupName"
- Change-StatusbarText -Text "Importing updates for WSUS group: $GroupName"
- $objGroup = Get-WsusGroupByName -Name $GroupName
- $Updates = $Group.ChildNodes
- $TotalUpdates = $Updates.Count
- $i = 0
- Foreach ($Update in $Updates)
- {
- $i++
- $UpdateGUID = Get-XmlValue -XML $Update.UpdateID
- if ($UpdateGUID -ne "")
- {
- $UpdateKB = $Update.UpdateKB
- Show-Progress -CurrentItem $i -Step $SYSTEM_DEFAULT_SHOW_PROGRESS_STEP -TotalCount $TotalUpdates -Template "Importing updates for $GroupName. Last processed is KB$UpdateKB"
- #Write-Status -Message $("Importing update $i of $TotalUpdates" + ": KB$UpdateKB")
- #Находим Update с таким ID на сервере:
- $UpdateGUID = [System.Guid]$UpdateGUID
- $objUpdateID = [Microsoft.UpdateServices.Administration.UpdateRevisionId]$UpdateGUID
- $objUpdate = $WSUS.GetUpdate($objUpdateID)
- #Получаем свойства обновления и его одобрения из XML-ки, преобразовываем все это к нужным типам
- [DateTime]$UpdateApprovalDeadline = Get-XmlValue -XML $Update.UpdateApprovalDeadLine
- [Microsoft.UpdateServices.Administration.UpdateApprovalAction]$UpdateApprovalAction = Get-XmlValue -XML $Update.UpdateApprovalAction
- if ($Update.UpdateIsDeclined -eq "true")
- {
- $UpdateIsDeclined = $true
- } else
- {
- $UpdateIsDeclined = $false
- }
- #Подтверждаем обновление
- $objUpdate.Approve($UpdateApprovalAction,$objGroup,$UpdateApprovalDeadline) | Out-Null
- #Ставим статус "Отменен"
- $objUpdate.IsDeclined = $UpdateIsDeclined
- }
- }
- }
- Write-Status -Message "Import finished for group: $GroupName"
- Change-StatusbarText -Text "Import finished for group: $GroupName"
- }
- }
- Function Copy-Approvals([STRING]$SourceGroupName,[STRING]$DestGroupName)
- {
- Start-WSUSSync | Out-Null
- Write-Status -Message "Started copying approvals from $SourceGroupName to $DestGroupName"
- Change-StatusbarText -Text "Started copying approvals from $SourceGroupName to $DestGroupName"
- $objSourceGroup = Get-WsusGroupByName -Name $SourceGroupName
- $objDestGroup = Get-WsusGroupByName -Name $DestGroupName
- $wsus = Get-WsusServerInstance
- $ApprovedUpdates = Get-UpdatesApprovedToGroup -GroupName $SourceGroupName
- #$Updates = $wsus.GetUpdates()
- $TotalCount = $ApprovedUpdates.Count
- $i = 0
- if ($ApprovedUpdates -ne $null)
- {
- foreach ($Update in $ApprovedUpdates)
- {
- $i++
- $UpdateKB = $Update.objUpdate.KnowledgebaseArticles
- Show-Progress -CurrentItem $i -Step $SYSTEM_DEFAULT_SHOW_PROGRESS_STEP -TotalCount $TotalCount -Template "Copying approvals from $SourceGroupName to $DestGroupName. Last processed is $UpdateKB"
- #Write-Status -Message $("Copying update $i of $TotalCount" + ": KB$UpdateKB")
- $UpdateApprovalDeadline = $Update.objApproval.Deadline
- $UpdateApprovalAction = $Update.objApproval.Action
- $Update.objUpdate.Approve($UpdateApprovalAction,$objDestGroup,$UpdateApprovalDeadline) | Out-Null
- }
- }
- Write-Status -Message "Finished copying approvals from $SourceGroupName to $DestGroupName"
- Change-StatusbarText -Text "Finished copying approvals from $SourceGroupName to $DestGroupName"
- }
- function Show-Progress([STRING]$Template,[LONG]$TotalCount,[LONG]$CurrentItem,[BYTE]$Step)
- {
- $Delta = [Math]::Round($Step * $TotalCount / 100)
- $M = $CurrentItem % $Delta
- $Message = $Template + " ($CurrentItem of $TotalCount)"
- Write-Status -Message $Message
- if (($CurrentItem -eq 1) -or ($M -eq 0) -or ($CurrentItem -eq $TotalCount))
- {
- Change-StatusbarText -Text $Message
- }
- }
- Function Change-StatusbarText([STRING]$Text)
- {
- $StatusBar.Text = $Text
- $MainForm.Refresh() | Out-Null
- }
- #Функция вывода данных о происходящем: пишет в статусную строку, лог, консоль, STDOut, еще куда-то: в зависимости от
- #режима запуска и других условий
- Function Write-Status([STRING]$Message)
- {
- if ($Message -ne " ")
- {
- [String]$DT = $(Get-Date)
- [String]$Str = $($DT + " " + $Message)
- }else
- {
- $Str = " "
- }
- if ($Script:RunMode -eq $SCRIPT_RUN_MODE_CLI)
- {
- Write-Host $Str
- }
- If (($Script:gLogFile -ne "") -and ($Script:gLogFile -ne $null))
- {
- # echo $Message + "`n" >> $Script:gLogFile -
- Write-Output $Str | Out-File -FilePath $Script:gLogFile -Append
- }
- # if ($Script:RunMode -eq $SCRIPT_RUN_MODE_CLI)
- # {
- #
- # }
- # elseif ($Script:RunMode -eq $SCRIPT_RUN_MODE_GUI)
- # {
- # Change-StatusbarText -Text $Message
- # }
- }
- Function Create-Directory ([STRING]$PATH)
- {
- $ErrorActionPreference = "SilentlyContinue"
- New-Item -type directory -path $PATH -ea 0
- trap
- {
- Write-Status -Message $_
- continue
- }
- }
- Function Change-StatusbarText([STRING]$Text)
- {
- $StatusBar.Text = $Text
- $MainForm.Refresh() | Out-Null
- }
- Function Get-RegValue([STRING]$Param,$DefaultValue)
- {
- $ErrorActionPreference = "silentlycontinue"
- $Value = $null
- $Value = (get-itemproperty "registry::$REGISTRY_HKCU_STORE_PATHES_KEY")."$Param"
- trap {continue}
- If ($Value -eq $null)
- {
- $Value = $DefaultValue
- }
- Return $Value
- }
- #Сохраняет знаяение выбора в реестре
- Function Set-RegValue ([STRING]$Value, [STRING]$Param)
- {
- $ErrorActionPreference = "SilentlyContinue"
- Trap {continue}
- New-Item -Path "registry::$REGISTRY_HKCU_STORE_PATHES_KEY" -ItemType "Directory"
- Set-ItemProperty -Force -Path "registry::$REGISTRY_HKCU_STORE_PATHES_KEY" -name "$Param" -Value $Value
- }
- #Определяет (неточно), является ли переданная строка путем к папке или файлу
- Function Get-TypeOfFSObject([STRING]$Path)
- {
- $ErrorActionPreference = "silentlycontinue"
- $File = $FILESYSTEM_OBJECT_TYPE_FILE
- $Folder = $FILESYSTEM_OBJECT_TYPE_FOLDER
- $Res = $null
- $FSObject = $null
- $FSObject = Get-Item $Path | Out-Null
- #Если объект таки есть в системе, значит его тип можно узнать точно
- if ($FSObject -ne $null)
- {
- #Смотрим, является ли элемент каталогом
- if ($FSObject.Attributes -eq "Directory")
- {
- Return $Folder
- }
- else #Элемент - не каталог, значит, - он - файл
- {
- Return $File
- }
- }
- else #Если объект не существует, будем пытаться распарсить строку
- {
- #Несуществующий путь, оканчивающийся на "\" - скорее всего, папка
- if ($Path -match "^.*\\$")
- {
- Return $Folder
- }
- #Несуществующий элемнт, имеющий точку в последней части пути - скорее всего,
- #файл
- $Leaf = Split-Path -Leaf $Path
- if ($Leaf -match "^.*\..*$")
- {
- Return $File
- } else #Если точки нет, то в Винде это, скорее всего, все таки папка
- {
- Return $Folder
- }
- }
- Trap {continue}
- }
- #Отрисовывает диалог выбора файла. Возвращает путь, выбранный пользователем
- function Open-FIleDialog([STRING]$InitialPath,[String]$DialogType)
- {
- if ($DialogType -eq "System.Windows.Forms.OpenFileDialog")
- {
- $OpenFileForm = New-Object System.Windows.Forms.OpenFileDialog
- }
- elseif ([STRING]$InitialPath,[TYPE]$DialogType)
- {
- $OpenFileForm = New-Object System.Windows.Forms.SaveFileDialog
- }
- $OpenFileForm.InitialDirectory = [STRING]$InitialPath
- $OpenFileForm.Filter = "WSUS admin tool files(*.waf)|*.waf|All files (*.*)|*.*"
- $Show = $OpenFileForm.ShowDialog()
- If ($Show -eq "OK")
- {
- Return $OpenFileForm.FileName
- }
- Else
- {
- #Write-Error "Operation cancelled by user."
- }
- }
- #Основная функция, запускаемая по кнопке "Выполнить"
- Function Start-Run()
- {
- Change-StatusbarText -Text "Saving current settings..."
- Save-Settings | Out-Null
- Start-WSUSActions | Out-Null
- Change-StatusbarText -Text "Задайте нужные параметры и нажмите кнопку `"Выполнить`""
- $Res = &($Script:gLogFile)
- }
- Function Form-Close()
- {
- $MainForm.Close()
- Save-Settings | Out-Null
- }
- #Показывает пользователюю сообщение
- Function Show-Message([STRING]$Title,[STRING]$Text,[Windows.Forms.MessageBoxButtons]$Buttons,[Windows.Forms.MessageBoxIcon]$Icon)
- {
- [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
- [Windows.Forms.MessageBox]::Show($Text, $Title, $Buttons, $Icon)
- }
- #Проверяет, все ли данные заполены корректно
- function Check-EnteredData()
- {
- }
- function Remove-File([STRING]$File)
- {
- $ErrorActionPreference = "SilentlyContinue"
- Remove-Item $File -Force | Out-Null
- trap
- {
- continue
- }
- }
- #Сохраняет значения параметров приложеня в реестр
- Function Save-Settings()
- {
- $Controls = $MainForm.Controls
- Foreach ($Control in $Controls)
- {
- #Если это чекбокс, сохраним его состояние
- if ($Control.GetType() -eq [System.Windows.Forms.CheckBox])
- {
- $Res = Set-RegValue -Value $Control.Checked -Param $Control.Name
- }
- #Если это поле ввода, сохраним его текст
- elseif ($Control.GetType() -eq [System.Windows.Forms.TextBox])
- {
- $Res = Set-RegValue -Value $Control.Text -Param $Control.Name
- }
- }
- }
- #Загружает значения основных параметров из реестра
- Function Load-Settings()
- {
- $ErrorActionPreference = "silentlycontinue"
- $Values = get-itemproperty "registry::$REGISTRY_HKCU_STORE_PATHES_KEY"
- $Controls = $MainForm.Controls
- Foreach ($Control in $Controls)
- {
- #Если это чекбокс, считываем значение его состояния
- if ($Control.GetType() -eq [System.Windows.Forms.CheckBox])
- {
- $STRChecked = Get-RegValue -Param $Control.Name -DefaultValue "false"
- if ($STRChecked -eq "true")
- {
- $CHK = $true
- }
- else
- {
- $CHK = $false
- }
- $Control.Checked = $CHK
- }
- #Если это поле ввода, считываем сохраненный текст
- elseif ($Control.GetType() -eq [System.Windows.Forms.TextBox])
- {
- $Control.Text = Get-RegValue -Param $Control.Name -DefaultValue $DEFAULT_USER_PATH
- }
- }
- }
- #Обработчик переключения чекбокса для $DoApprovalImportCheckBox
- Function DoApprovalImportCheckBox_OnClick()
- {
- If ($DoApprovalImportCheckBox.Checked -eq $false)
- {
- $TextBoxInputFile.Enabled = $false
- $BrowseButtonInputFile.Enabled = $false
- } else
- {
- $TextBoxInputFile.Enabled = $true
- $BrowseButtonInputFile.Enabled = $true
- }
- }
- #Обработчик переключения чекбокса для $DoApprovalImportCheckBox
- Function DoApprovalExportCheckBox_OnClick()
- {
- If ($DoApprovalExportCheckBox.Checked -eq $false)
- {
- $TextBoxOutputFIle.Enabled = $false
- $BrowseButtonOutputFIle.Enabled = $false
- } else
- {
- $TextBoxOutputFIle.Enabled = $true
- $BrowseButtonOutputFIle.Enabled = $true
- }
- }
- #Запускает на исполнения действия над базой WSUS (с учетом режима запуска, настроек и т.д.)
- function Start-WSUSActions()
- {
- Change-StatusbarText -Text "Start executing WSUS actions..."
- #Если мы в графическом режиме, берем настройки прямо с формы
- if ($Script:RunMode -eq $SCRIPT_RUN_MODE_GUI)
- {
- $DoCopyServerApprovals = $DoCopyApprovalsForServers.Checked
- $DoCopyWKSApprovals = $DoCopyApprovalsForWorkStations.Checked
- $DoExportApprovals = $DoApprovalExportCheckBox.Checked
- $DoImportApprovals = $DoApprovalImportCheckBox.Checked
- $IputFileName = $TextBoxInputFile.Text
- $OutputFileName = $TextBoxOutputFIle.Text
- }
- #Если мы в текстовом режиме - берем настройки из параметров скрипта
- elseif ($Script:RunMode -eq $SCRIPT_RUN_MODE_CLI)
- {
- $DoCopyServerApprovals = $ServersCopyTestApprovals
- $DoCopyWKSApprovals = $WorkstationsCopyTestApprovals
- #Если параметр $DoExportToFile - пустой, значит экспорт не делаем
- if ($DoExportToFile -eq "")
- {
- $DoExportApprovals = $false
- } else
- {
- $DoExportApprovals = $true
- }
- #Если параметр $DoImportFromFile - пустой, импорт не делаем
- if ($DoImportFromFile -eq "")
- {
- $DoImportApprovals = $false
- }else
- {
- $DoImportApprovals = $true
- }
- $IputFileName = $DoImportFromFile
- $OutputFileName = $DoExportToFile
- }
- #Параметры определены, начинаем выполнение
- #Подтверждение "тестовых" разрешений на рабочие станции
- if ($DoCopyWKSApprovals -eq $true)
- {
- Copy-Approvals -SourceGroupName $WSUS_GROUP_NAME_WORKSTATIONS_TEST -DestGroupName $WSUS_GROUP_NAME_WORKSTATIONS_PROD | Out-Null
- }
- #Подтверждение "тестовых" разрешений на серверы
- if ($DoCopyServerApprovals -eq $true)
- {
- Copy-Approvals -SourceGroupName $WSUS_GROUP_NAME_SERVERS_TEST -DestGroupName $WSUS_GROUP_NAME_SERVERS_PROD | Out-Null
- }
- #Экспорт подтверждений в файл
- if ($DoExportApprovals -eq $true)
- {
- Export-Approvals -FilePath $OutputFileName -ApprovedGroupsNames $WSUS_GROUPS_TO_EXPORT | Out-Null
- }
- #Импорт подтверждений из файла
- if ($DoImportApprovals -eq $true)
- {
- Import-Approvals -FilePath $IputFileName | Out-Null
- }
- }
- Function Start-WSUSSync()
- {
- Write-Status -Message "Starting WSUS Synchronization..."
- Change-StatusbarText -Text "Starting WSUS Synchronization..."
- $Res = $false
- $wsus = Get-WsusServerInstance
- $WSUSSubscription = $wsus.GetSubscription()
- # $PrevTime = $WSUSSubscription.GetLastSynchronizationInfo().EndTime
- $Sync = $WSUSSubscription.StartSynchronization()
- #Ждем, пока выполнится синхронизация
- $Try = 0
- while ($WSUSSubscription.GetSynchronizationStatus() -eq [Microsoft.UpdateServices.Administration.SynchronizationStatus]::Running)
- {
- $Try++
- Change-StatusbarText -Text "Waiting WSUS Synchronization: try $Try"
- Start-Sleep -Seconds $SYSTEM_DEFAULT_SLEEP_TIME
- }
- if ($WSUSSubscription.GetLastSynchronizationInfo().Result -eq [Microsoft.UpdateServices.Administration.SynchronizationResult]::Succeeded)
- {
- $Res = $true
- Write-Status -Message "Starting WSUS succeeded"
- Change-StatusbarText -Text "Starting WSUS succeeded"
- }
- else
- {
- Write-Status -Message "Starting WSUS Synchronization failed"
- Change-StatusbarText -Text "Starting WSUS Synchronization failed"
- }
- Return $Res
- }
- cls
- #$res = Start-WSUSSync
- $wsus=$null
- $Script:gLogLevel = 5
- if (-not (($PathToLog -ne "") -and (Test-Path $PathToLog -PathType Any -IsValid))) {
- $PathToLog = [System.IO.Path]::GetTempPath()
- }
- $Script:gLogFile = Join-Path $PathToLog $SCRIPT_LOG_FILE_NAME
- Remove-File -File $Script:gLogFile | Out-Null
- echo "" > $Script:gLogFile
- #Загружаем библиотеку управления WSUS.
- [reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")|out-null
- [reflection.assembly]::LoadWithPartialName("System.Management.Automation")|out-null
- #Определяем значение путей по умолчанию. В качестве такого пути будем использовать
- #домашний диск пользователя
- $DEFAULT_USER_PATH = $ENV:TEMP
- $DEFAULT_USER_PATH = Join-Path $DEFAULT_USER_PATH "\"
- #Определяем режим запуска сценария. Если все параемтры - "умолчальные", значит - графический
- If (($DoImportFromFile -eq "") -and ($DoExportToFile -eq "") `
- -and ($ServersCopyTestApprovals -eq $false) `
- -and ($WorkstationsCopyTestApprovals -eq $false))
- {
- $Script:RunMode = $SCRIPT_RUN_MODE_GUI
- } else
- {
- $Script:RunMode = $SCRIPT_RUN_MODE_CLI
- }
- #Если режим запуска - графический, рисуем GUI, иначе - сразу запускаем выполнение
- if ($Script:RunMode -eq $SCRIPT_RUN_MODE_GUI)
- {
- #----------------<GUI>----------------------------------------------------------
- #Подгружаем библиотеки.
- [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
- [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
- #Создаем форму, на которой все будет отрисовываться
- $MainForm = New-Object System.Windows.Forms.Form
- $MainForm.Name = "MainForm"
- $MainForm.Text = $SCRIPT_NAME_STRING + $SCRIPT_VERSION_NUMBER
- $MainForm.Size = New-Object System.Drawing.Size(790,282)
- #$MainForm.MinimumSize = New-Object System.Drawing.Size(790,282)
- #$MainForm.MaximumSize = New-Object System.Drawing.Size(1054,282)
- $MainForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
- $MainForm.StartPosition = "CenterScreen"
- $MainForm.MaximizeBox = $false
- $MainForm.KeyPreview = $True
- #Прописываем основные клавиши формы
- $MainForm.Add_KeyDown(
- {
- if ($_.KeyCode -eq "Enter")
- {
- $temp = Start-Run
- }
- })
- $MainForm.Add_KeyDown(
- {
- if ($_.KeyCode -eq "Escape")
- {
- $MainForm.Close()
- }
- })
- #Обработчик закрытия формы
- $MainForm.add_Closing(
- {
- Save-Settings | Out-Null
- }
- )
- #------Элементы формы
- #Чекбокс "Выполнить операцию импорта"
- $DoApprovalImportCheckBox = New-Object System.Windows.Forms.CheckBox
- $DoApprovalImportCheckBox.Name = "DoApprovalImportCheckBox"
- $DoApprovalImportCheckBox.Location = New-Object System.Drawing.Size(8,14)
- $DoApprovalImportCheckBox.size = new-object System.Drawing.Size(400,20)
- $DoApprovalImportCheckBox.Text = "Импорт одобрений. Укажите путь к файлу:"
- $DoApprovalImportCheckBox.Checked = $false
- $DoApprovalImportCheckBox.Add_Click({
- DoApprovalImportCheckBox_OnClick | Out-Null
- })
- $MainForm.Controls.Add($DoApprovalImportCheckBox) | Out-Null
- #Поле ввода пути к файлу с данными для импорта
- $TextBoxInputFile = New-Object System.Windows.Forms.TextBox
- $TextBoxInputFile.Name = "TextBoxInputFile"
- $TextBoxInputFile.Location = New-Object System.Drawing.Size(8,34)
- $TextBoxInputFile.Size = New-Object System.Drawing.Size(688,20)
- #$TextBoxInputFile.Text = Get-RegValue -Param $REGISTRY_STORE_INPUT_FILE_VALUE -DefaultValue $DEFAULT_USER_PATH
- $TextBoxInputFile.Anchor = "Top, Left, Right"
- $MainForm.Controls.Add($TextBoxInputFile) | Out-Null
- #Кнопка открытия диалога выбора пути к папке с входными файлами
- $BrowseButtonInputFile = New-Object System.Windows.Forms.Button
- $BrowseButtonInputFile.Name = "BrowseButtonInputFile"
- $BrowseButtonInputFile.Location = New-Object System.Drawing.Size(700,31)
- $BrowseButtonInputFile.Size = New-Object System.Drawing.Size(75,25)
- $BrowseButtonInputFile.Text = "Выбрать"
- $BrowseButtonInputFile.Add_Click({
- $SelPath = Open-FIleDialog -InitialPath $TextBoxInputFile.Text -DialogType "System.Windows.Forms.OpenFileDialog"
- if (($SelPath -ne $null) -and ($SelPath -ne ""))
- {
- $TextBoxInputFile.Text = $SelPath
- $Res = Set-RegValue -Value $SelPath -Param $REGISTRY_STORE_INPUT_FILE_VALUE
- }
- })
- $BrowseButtonInputFile.Anchor = "Top, Right"
- $MainForm.Controls.Add($BrowseButtonInputFile) | Out-Null
- #Чекбокс "Выполнить операцию экспорта"
- $DoApprovalExportCheckBox = New-Object System.Windows.Forms.CheckBox
- $DoApprovalExportCheckBox.Name = "DoApprovalExportCheckBox"
- $DoApprovalExportCheckBox.Location = New-Object System.Drawing.Size(8,60)
- $DoApprovalExportCheckBox.size = new-object System.Drawing.Size(400,20)
- $DoApprovalExportCheckBox.Text = "Экспорт одобрений. Укажите путь к файлу:"
- $DoApprovalExportCheckBox.Checked = $false
- $DoApprovalExportCheckBox.Add_Click({
- DoApprovalExportCheckBox_OnClick | Out-Null
- })
- $MainForm.Controls.Add($DoApprovalExportCheckBox) | Out-Null
- #Поле ввода пути к результрующему файла (для экспорта)
- $TextBoxOutputFIle = New-Object System.Windows.Forms.TextBox
- $TextBoxOutputFIle.Name = "TextBoxOutputFIle"
- $TextBoxOutputFIle.Location = New-Object System.Drawing.Size(8,80)
- $TextBoxOutputFIle.Size = New-Object System.Drawing.Size(688,20)
- #$TextBoxOutputFIle.Text = Get-RegValue -Param $REGISTRY_STORE_OUTPUT_FILE_VALUE -DefaultValue $DEFAULT_USER_PATH
- $TextBoxOutputFIle.Anchor = "Top, Left, Right"
- $MainForm.Controls.Add($TextBoxOutputFIle) | Out-Null
- #Кнопка открытия диалога выбора пути к папке, в которую будет сохранен результат
- $BrowseButtonOutputFIle = New-Object System.Windows.Forms.Button
- $BrowseButtonOutputFIle.Name = "BrowseButtonOutputFIle"
- $BrowseButtonOutputFIle.Location = New-Object System.Drawing.Size(700,77)
- $BrowseButtonOutputFIle.Size = New-Object System.Drawing.Size(75,25)
- $BrowseButtonOutputFIle.Text = "Выбрать"
- $BrowseButtonOutputFIle.Add_Click({
- $SelPath = Open-FIleDialog -InitialPath $TextBoxOutputFIle.Text "System.Windows.Forms.SaveFileDialog"
- if (($SelPath -ne $null) -and ($SelPath -ne ""))
- {
- $TextBoxOutputFIle.Text = $SelPath
- $Res = Set-RegValue -Value $SelPath -Param $REGISTRY_STORE_OUTPUT_FILE_VALUE
- }
- })
- $BrowseButtonOutputFIle.Anchor = "Top, Right"
- $MainForm.Controls.Add($BrowseButtonOutputFIle) | Out-Null
- #------
- #Чекбокс "Перенос разрешений с тестовой группы серверов на боевую"
- $DoCopyApprovalsForServers = New-Object System.Windows.Forms.CheckBox
- $DoCopyApprovalsForServers.Name = "DoCopyApprovalsForServers"
- $DoCopyApprovalsForServers.Location = New-Object System.Drawing.Size(8,132)
- $DoCopyApprovalsForServers.size = new-object System.Drawing.Size(400,20)
- $DoCopyApprovalsForServers.Text = "для серверов"
- $DoCopyApprovalsForServers.Checked = $false
- $DoCopyApprovalsForServers.Add_Click({
- # Write-Host click
- })
- $MainForm.Controls.Add($DoCopyApprovalsForServers) | Out-Null
- #Чекбокс "Перенос разрешений с тестовой группы рабочих станций на боевую"
- $DoCopyApprovalsForWorkStations = New-Object System.Windows.Forms.CheckBox
- $DoCopyApprovalsForWorkStations.Name = "DoCopyApprovalsForWorkStations"
- $DoCopyApprovalsForWorkStations.Location = New-Object System.Drawing.Size(8,162)
- $DoCopyApprovalsForWorkStations.size = new-object System.Drawing.Size(400,20)
- $DoCopyApprovalsForWorkStations.Text = "для рабочих станций"
- $DoCopyApprovalsForWorkStations.Checked = $false
- $DoCopyApprovalsForWorkStations.Add_Click({
- # Write-Host click
- })
- $MainForm.Controls.Add($DoCopyApprovalsForWorkStations) | Out-Null
- #Кнопка "Выполнить". Запускает на исполнение основную функцию.
- $RunButton = New-Object System.Windows.Forms.Button
- $RunButton.Name = "RunButton"
- #$RunButton.Location = New-Object System.Drawing.Size(625,195)
- $RunButton.Location = New-Object System.Drawing.Size(700,195)
- $RunButton.Size = New-Object System.Drawing.Size(75,25)
- $RunButton.Anchor = "Bottom, Right"
- $RunButton.Text = "Выполнить"
- $RunButton.Add_Click(
- {
- Start-Run | Out-Null
- })
- $MainForm.Controls.Add($RunButton)| Out-Null
- #Кнопка отмены. Закрывает форму.
- #$CancelButton = New-Object System.Windows.Forms.Button
- #$CancelButton.Name = "CancelButton"
- #$CancelButton.Location = New-Object System.Drawing.Size(700,195)
- #$CancelButton.Size = New-Object System.Drawing.Size(75,25)
- #$CancelButton.Text = "Отмена"
- #$CancelButton.Anchor = "Bottom, Right"
- #$CancelButton.Add_Click({
- # Form-Close | Out-Null
- # })
- #$MainForm.Controls.Add($CancelButton) | Out-Null
- #Строка статуса
- $StatusBar = New-Object System.Windows.Forms.StatusBar
- $StatusBar.Name = "StatusBar"
- $StatusBar.Text = $DEFAULT_STATUS_BAR_TEXT
- $MainForm.Controls.Add($StatusBar) | Out-Null
- #--------------------------
- #Групбоксы - декоративные элементы
- ##Группировка полей путей
- $BrowseGroupBox = New-Object System.Windows.Forms.GroupBox
- $BrowseGroupBox.Location = New-Object System.Drawing.Size(3,3)
- $BrowseGroupBox.Size = New-Object System.Drawing.Size(776,105)
- $BrowseGroupBox.Anchor = "Top, Left, Right"
- $BrowseGroupBox.Text = "Обмен данными:"
- $MainForm.Controls.Add($BrowseGroupBox) | Out-Null
- ##Группиров чекбоксов
- $CheckBoxesGroupBox = New-Object System.Windows.Forms.GroupBox
- $CheckBoxesGroupBox.Location = New-Object System.Drawing.Size(3,110)
- $CheckBoxesGroupBox.Size = New-Object System.Drawing.Size(776,80)
- $CheckBoxesGroupBox.Text = "Одобрить тестовые обновления:"
- $CheckBoxesGroupBox.Anchor = "Top, Left, Right, Bottom"
- $MainForm.Controls.Add($CheckBoxesGroupBox) | Out-Null
- #Загружаем настройки от прошлого сеанса из реестра
- Load-Settings | Out-Null
- #Обрабатываем чекбоксы
- DoApprovalImportCheckBox_OnClick | Out-Null
- DoApprovalExportCheckBox_OnClick | Out-Null
- #Показываем форму
- [void] $MainForm.ShowDialog() | Out-Null
- #----------------</GUI>----------------------------------------------------------
- }
- else #Если мы работаем в режиме командной строки
- {
- Start-WSUSActions | out-null
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement