User Tools

Site Tools


userspace:windows_updates_-_powershell

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
userspace:windows_updates_-_powershell [2017/03/02 09:31]
trabs-ol created
userspace:windows_updates_-_powershell [2021/08/23 08:37] (current)
Line 1: Line 1:
-Mit diesem Script werden so lange Updates intstalliert bis keine mehr vorliegen. Die Updates werden nur nach 19 Uhr und vor 7 Uhr installiert um den User nicht an der Anmeldung zu hindern. Aussnahme: Der Rechner wurde neu installiert, dann werden unabhängig von der Uhrzeit alle Updates installiert. Mit dem ONCE Script werden immer alle Updates installiert, unabhänig von der Tageszeit.+====== WSUS Updates Powershell ======
  
-VoraussetzungenPowershell Version >= 4+Mit diesem Script werden so lange Updates intstalliert bis keine mehr vorliegen. Die Updates werden nur nach 19 Uhr und vor 7 Uhr installiert um den User nicht an der Anmeldung zu hindern. AussnahmeDer Rechner wurde neu installiert, dann werden unabhängig von der Uhrzeit alle Updates installiert. Mit dem ONCE Script werden immer alle Updates installiert, unabhängig von der Tageszeit.
  
 +Voraussetzungen: Powershell Version >= 4.0
 +
 +Getestet unter Windows 7 x64 SP1
 +
 +Logging des Scriptes erfolgt in C:\tmp\windows-update-opsi.log
 +
 +Ordnerstruktur:
 +
 +CLIENT_DATA
 +  * install-updates.ps1
 +  * install-updates-once.ps1
 +  * once64.ins
 +  * setup64.ins
 +  * windows_update_icon.png (nur fürs gute Aussehen)
 +
 +OPSI
 +  * control
 +
 +setup64.ins
 +
 +<code winst>
 +; Copyright (c) uib gmbh (www.uib.de)
 +; This sourcecode is owned by uib
 +; and published under the Terms of the General Public License.
 +; credits: http://www.opsi.org/en/credits/
 +; comment
 +
 +[Actions]
 +requiredWinstVersion >= "4.11.4.7"
 +AutoActivityDisplay = true
 +StayOnTop = false
 +
 +DefVar $LogDir$
 +DefVar $ProductId$  
 +DefVar $MinimumSpace$
 +DefVar $ExitCode$
 +
 +Set $LogDir$ = "%SystemDrive%\tmp"
 +
 +; ----------------------------------------------------------------
 +; - Please edit the following values                             -
 +; ----------------------------------------------------------------
 +;$ProductId$ should be the name of the product in opsi
 +; therefore please: only lower letters, no umlauts, 
 +; no white space use '-' as a seperator
 +Set $ProductId$       = "install-windows-updates"
 +Set $MinimumSpace$    = "500 MB"
 +; ----------------------------------------------------------------
 +
 +if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$))
 + LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$
 + isFatalError
 + ; Stop process and set installation status to failed
 +else
 + comment "Show product picture"
 + ShowBitmap "%ScriptPath%\windows_update_icon.png" "Windows Update"
 +
 +        Files_Install /Sysnative
 + Message "Installiere Windows Updates. Dies kann mehrere Stunden dauern."
 + DosInAnIcon_WindowsUpate
 + Sub_check_exitcode
 +
 +endif
 +
 +[Files_Install]
 +CheckTargetPath = "%Systemdrive%\tmp"
 +copy -u "%ScriptPath%\install-updates.ps1" "%Systemdrive%\tmp\"
 +
 +[DosInAnIcon_WindowsUpate]
 +"%SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy ByPass -command "& { "%Systemdrive%\tmp\install-updates.ps1"; exit $lastexitcode }"
 +
 +[Sub_check_exitcode]
 +comment "Test for installation success via exit code"
 +set $ExitCode$ = getLastExitCode
 +; informations to exit codes see
 +; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx
 +; http://msdn.microsoft.com/en-us/library/aa368542.aspx
 +if ($ExitCode$ = "0")
 + comment "Looks good: setup program gives exitcode zero"
 +else
 + comment "Setup program gives a exitcode unequal zero: " + $ExitCode$
 + if ($ExitCode$ = "1605")
 + comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed."
 + comment "Uninstall of a not installed product failed - no problem"
 + else
 + if ($ExitCode$ = "1641")
 + comment "looks good: setup program gives exitcode 1641"
 + comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success."
 + else
 + if ($ExitCode$ = "3010")
 + comment "looks good: setup program gives exitcode 3010"
 + comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success."
 + ExitWindows /ImmediateReboot
 + else
 + logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$
 + isFatalError
 + endif
 + endif
 + endif
 +endif
 +</code>
 +
 +once64.ins
 +<code winst>
 +; Copyright (c) uib gmbh (www.uib.de)
 +; This sourcecode is owned by uib
 +; and published under the Terms of the General Public License.
 +; credits: http://www.opsi.org/en/credits/
 +; comment
 +
 +[Actions]
 +requiredWinstVersion >= "4.11.4.7"
 +AutoActivityDisplay = true
 +StayOnTop = false
 +
 +DefVar $LogDir$
 +DefVar $ProductId$  
 +DefVar $MinimumSpace$
 +DefVar $ExitCode$
 +
 +Set $LogDir$ = "%SystemDrive%\tmp"
 +
 +; ----------------------------------------------------------------
 +; - Please edit the following values                             -
 +; ----------------------------------------------------------------
 +;$ProductId$ should be the name of the product in opsi
 +; therefore please: only lower letters, no umlauts, 
 +; no white space use '-' as a seperator
 +Set $ProductId$       = "install-windows-updates"
 +Set $MinimumSpace$    = "500 MB"
 +; ----------------------------------------------------------------
 +
 +if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$))
 + LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$
 + isFatalError
 + ; Stop process and set installation status to failed
 +else
 + comment "Show product picture"
 + ShowBitmap "%ScriptPath%\windows_update_icon.png" "Windows Update"
 +
 +        Files_Install /Sysnative
 + Message "Installiere Windows Updates. Dies kann mehrere Stunden dauern."
 + DosInAnIcon_WindowsUpate
 + Sub_check_exitcode
 +
 +endif
 +
 +[Files_Install]
 +CheckTargetPath = "%Systemdrive%\tmp"
 +copy -u "%ScriptPath%\install-updates-once.ps1" "%Systemdrive%\tmp\"
 +
 +[DosInAnIcon_WindowsUpate]
 +"%SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -command "& { "%Systemdrive%\tmp\install-updates-once.ps1"; exit $lastexitcode }"
 +
 +[Sub_check_exitcode]
 +comment "Test for installation success via exit code"
 +set $ExitCode$ = getLastExitCode
 +; informations to exit codes see
 +; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx
 +; http://msdn.microsoft.com/en-us/library/aa368542.aspx
 +if ($ExitCode$ = "0")
 + comment "Looks good: setup program gives exitcode zero"
 +else
 + comment "Setup program gives a exitcode unequal zero: " + $ExitCode$
 + if ($ExitCode$ = "1605")
 + comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed."
 + comment "Uninstall of a not installed product failed - no problem"
 + else
 + if ($ExitCode$ = "1641")
 + comment "looks good: setup program gives exitcode 1641"
 + comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success."
 + else
 + if ($ExitCode$ = "3010")
 + comment "looks good: setup program gives exitcode 3010"
 + comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success."
 + ExitWindows /ImmediateReboot
 + else
 + logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$
 + isFatalError
 + endif
 + endif
 + endif
 +endif
 +</code>
 +
 +control
 +
 +<code>
 +[Package]
 +version: 19
 +depends: 
 +incremental: False
 +
 +[Product]
 +type: localboot
 +id: install-windows-updates
 +name: Updates für Windows installieren
 +description: 
 +advice: 
 +version: 4.0
 +priority: -80
 +licenseRequired: False
 +productClasses: 
 +setupScript: setup64.ins
 +uninstallScript: 
 +updateScript: 
 +alwaysScript: 
 +onceScript: once64.ins
 +customScript: 
 +userLoginScript: 
 +</code>
 +
 +install-updates.ps1
 +
 +<code>
 +function Write-Log
 +{
 +    [CmdletBinding()]
 +    param(
 +        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
 +        [Array[]]$logstring
 +    )
 +    foreach ($string in $logstring) {
 +        $nowDate = Get-Date -Format dd.MM.yyyy
 +        $nowTime = Get-Date -Format HH:mm:ss
 +        Write-Host $nowDate $nowTime $string
 +        Add-Content -LiteralPath $LogPath -Value "$nowDate $nowTime $string"
 +    }
 +}
 +
 +function Get-Timewindow
 +{
 +    $Now = Get-Date
 +    if (($Now.Hour -ge 7) -and ($Now.Hour -le 19))
 +    {
 +        Write-Log 'It is daytime. Check if System was just getting installed.'
 +        $InstallDate = ([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate)
 +        $OneDay = New-TimeSpan -Days 1
 +
 +        if ((($Now) -$InstallDate) -lt $OneDay)
 +        {
 +            Write-Log 'OS installation time is not older than 1 day. Windows Updates must be installed. Continue...'
 +        }
 +        else
 +        {
 +            Write-Log 'OS installation time is older than 1 day. Doing nothing because its day.'
 +            Write-Log '***** END *****'
 +            exit 0
 +        }
 +    }
 +    else
 +    {
 +        Write-Log 'It is night. Continue...'
 +    }
 +}
 +
 +function Get-Rebootrequired
 +{
 +    $objSystemInfo= New-Object -ComObject 'Microsoft.Update.SystemInfo'
 +    $RebootRequired = $objSystemInfo.RebootRequired
 +    if ($RebootRequired -eq $true)
 +    {
 +        Write-Log 'Need to reboot, rebooting...'
 +        exit 3010
 +    }
 +    else
 +    {
 +        Write-Log 'No need to reboot.'
 +    }
 +}
 +
 +function Get-InstallerStatus {
 +    $Busy = $true
 +    $lastWriteTimeCBSLos = (Get-Item C:\Windows\Logs\CBS\CBS.log).LastWriteTime
 +    $TimespanOneMinute = New-TimeSpan -Minutes 1
 +    while ($Busy -eq $true)
 +    {
 +        if (((Get-Date) -$lastWriteTimeCBSLos) -gt $TimespanOneMinute) {
 +            $Busy = $false
 +        }
 +        else {
 +            Write-Log 'Waiting for Trusted Installer...'
 +            Start-Sleep -Seconds 10
 +        }
 +    }
 +    
 +}
 +
 +
 +$LogPath = "$env:SystemDrive\tmp\windows-update-opsi.log"
 +$FirstRun = Test-Path -Path $LogPath
 +
 +Write-Log '***** START *****'
 +
 +Get-Timewindow
 +Get-Rebootrequired
 +Get-InstallerStatus
 +
 +Write-Log 'Searching for new Updates...'
 +
 +#GUI bauen
 +[System.Windows.Forms.Application]::EnableVisualStyles()
 +Add-Type -AssemblyName System.Windows.Forms
 +$Form = New-Object system.Windows.Forms.Form
 +$Form.Text = 'Windows-Update-Status'
 +$Form.Width = 430
 +$Form.Height = 100
 +$Form.TopMost = $True
 +$Form.AutoSizeMode = 'GrowAndShrink'
 +$Form.MinimizeBox = $False
 +$Form.MaximizeBox = $False
 +$Form.WindowState = 'Normal'
 +$Form.SizeGripStyle = 'Hide'
 +$Form.ShowInTaskbar = $False
 +$Form.StartPosition = 'CenterScreen'
 +$Font = New-Object System.Drawing.Font('Arial',12)
 +$Form.Font = $Font
 +$Label = New-Object System.Windows.Forms.Label
 +$Label.Text = 'Suche nach Windows Updates...'
 +$Label.AutoSize = $True
 +$Form.Controls.Add($Label)
 +$Form.Show()
 +$Form.Focus()
 +
 +$Session= New-Object -ComObject Microsoft.Update.Session
 +$Searcher= $Session.CreateUpdateSearcher()
 +
 +$SearchResults = $Searcher.Search("IsInstalled=0 and Type='Software'").Updates
 +if ($SearchResults.Count -eq 0 -and $FirstRun -eq $true)
 +{
 +    Write-Log 'No Updates found.'
 +    Write-Log '***** END *****'
 +    $Label.Text = 'Keine neuen Updates gefunden.'
 +    $Form.Refresh()
 +    Start-Sleep -Seconds 5
 +    $Form.Close()
 +    exit 0
 +}
 +
 +if ($SearchResults.Count -eq 0 -and $FirstRun -eq $false)
 +{
 +    Write-Log 'No Updates found, but it is the first time to search for updates. Reboot!'
 +    Write-Log '***** END *****'
 +    $Label.Text = 'Keine Updates gefunden, neuer Versuch...'
 +    $Form.Refresh()
 +    Start-Sleep -Seconds 5
 +    $form.Close()
 +    exit 3010
 +}
 +
 +foreach ($Update in $SearchResults) {
 +    $TotalUpdateSize = $Update.MaxDownloadSize + $TotalUpdateSize
 +    Write-Log "Found KB$($update.KBArticleIDs), Size: $([math]::Round($($update.MaxDownloadSize/1MB),2).ToString('0.00').PadLeft(6)) MB, Title: $($update.Title)"
 +}
 +
 +Write-Log "Summary: $($SearchResults.Count) new Update(s), $($($TotalUpdateSize/1MB).ToString('0.00')) MB to download."
 +$Label.Text = "$($SearchResults.Count) neue Update(s) gefunden."
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +Write-Log 'Starting Download...'
 +$Label.Text = 'Starte Download.'
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +
 +# ProgressBar bauen
 +$ProgressBarSize = New-Object System.Drawing.Size
 +$ProgressBarSize.Width = 400
 +$ProgressBarSize.Height = 20
 +$ProgressBar = New-Object System.Windows.Forms.ProgressBar
 +$ProgressBar.Left = 5
 +$ProgressBar.Top = 35
 +$ProgressBar.Style = 'Continuous'
 +$ProgressBar.Value = 0
 +$ProgressBar.Size = $ProgressBarSize
 +$Form.Controls.Add($ProgressBar)
 +
 +$ProgressInPercent = 0
 +$DownloadCount = 0
 +$DownloadSuccessCounter = 0
 +$DownloadFailedCounter = 0
 +
 +foreach ($DownloadItem in $SearchResults)
 +{
 +    $DownloadCount++
 +    $Downloader = $Session.CreateUpdateDownloader()
 +    $DownloadItems = New-Object -ComObject Microsoft.Update.UpdateColl
 +    $DownloadItems.Add($DownloadItem)
 +    $Downloader.Updates = $DownloadItems
 +    $DownloadResult = $Downloader.Download()
 +    if ($DownloadResult.ResultCode -eq 2) {
 +        $DownloadSuccessCounter++
 +        Write-Log "Successfully downloaded Update $DownloadCount of $($SearchResults.Count), KB$($DownloadItem.KBArticleIDs), Size: $(($DownloadItem.MaxDownloadSize/1MB).ToString('0.00')) MB, Title: $($DownloadItem.Title)"
 +        $ProgressInPercent = ($DownloadCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Download $DownloadCount von $($SearchResults.Count) erfolgreich."
 +        $Form.Refresh()
 +    }
 +    else {
 +        $DownloadFailedCounter++
 +        Write-Log "Failed downloading Update $DownloadCount of $($SearchResults.Count), KB$($DownloadItem.KBArticleIDs), Title: $($DownloadItem.Title)"
 +        $ProgressInPercent = ($DownloadCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Download $DownloadCount von $($SearchResults.Count) fehlgeschlagen."
 +        $Form.Refresh()
 +
 +    }
 +}
 +Write-Log "Summary: Successfully downloaded $DownloadSuccessCounter Updates, failed to download $DownloadFailedCounter Updates."
 +
 +Write-Log 'Starting Install...'
 +$ProgressBar.Value = 0
 +$Label.Text = 'Starte Installation...'
 +$Form.Refresh()
 +
 +$InstallCount = 0
 +$InstallSuccessCounter = 0
 +$InstallFailedCounter = 0
 +foreach ($InstallItem in $SearchResults)
 +{
 +    $InstallCount++
 +    $Installer = $Session.CreateUpdateInstaller()
 +    $InstallerItems = New-Object -ComObject Microsoft.Update.UpdateColl
 +    $InstallerItems.Add($InstallItem)
 +    $Installer.Updates = $InstallerItems
 +    $InstallResult = $Installer.Install()
 +    if ($InstallResult.ResultCode -eq 2) {
 +        $InstallSuccessCounter++
 +        Write-Log "Successfully installed Update $InstallCount of $($SearchResults.Count), KB$($InstallItem.KBArticleIDs), Title: $($InstallItem.Title)"
 +        $ProgressInPercent = ($InstallCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Update $InstallCount von $($SearchResults.Count) erfolgreich installiert."
 +        $Form.Refresh()
 +    }
 +    else {
 +        $InstallFailedCounter++
 +        Write-Log "Failed installing Update $InstallCount of $($SearchResults.Count), KB$($InstallItem.KBArticleIDs), Title: $($InstallItem.Title)"
 +        $ProgressInPercent = ($InstallCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Update $InstallCount von $($SearchResults.Count) fehlgeschlagen."
 +        $Form.Refresh()
 +    }
 +}
 +Write-Log "Summary: Successfully installed $InstallSuccessCounter Updates, failed to install $InstallFailedCounter Updates."
 +Write-Log 'Rebooting...'
 +Write-Log '***** END *****'
 +$Label.Text = "$InstallSuccessCounter Updates erfolgreich, $InstallFailedCounter Updates fehlgeschlagen."
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +$Label.Text = 'Neustart des Systems'
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +$Form.Close()
 +exit 3010
 +</code>
 +
 +install-updates-once.ps1
 +
 +<code>
 +function Write-Log
 +{
 +    [CmdletBinding()]
 +    param(
 +        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
 +        [Array[]]$logstring
 +    )
 +    foreach ($string in $logstring) {
 +        $nowDate = Get-Date -Format dd.MM.yyyy
 +        $nowTime = Get-Date -Format HH:mm:ss
 +        Write-Host $nowDate $nowTime $string
 +        Add-Content -LiteralPath $LogPath -Value "$nowDate $nowTime $string"
 +    }
 +}
 +
 +function Get-Timewindow
 +{
 +    $Now = Get-Date
 +    if (($Now.Hour -ge 7) -and ($Now.Hour -le 19))
 +    {
 +        Write-Log 'It is daytime. Check if System was just getting installed.'
 +        $InstallDate = ([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate)
 +        $OneDay = New-TimeSpan -Days 1
 +
 +        if ((($Now) -$InstallDate) -lt $OneDay)
 +        {
 +            Write-Log 'OS installation time is not older than 1 day. Windows Updates must be installed. Continue...'
 +        }
 +        else
 +        {
 +            Write-Log 'OS installation time is older than 1 day. Doing nothing because its day.'
 +            Write-Log '***** END *****'
 +            exit 0
 +        }
 +    }
 +    else
 +    {
 +        Write-Log 'It is night. Continue...'
 +    }
 +}
 +
 +function Get-Rebootrequired
 +{
 +    $objSystemInfo= New-Object -ComObject 'Microsoft.Update.SystemInfo'
 +    $RebootRequired = $objSystemInfo.RebootRequired
 +    if ($RebootRequired -eq $true)
 +    {
 +        Write-Log 'Need to reboot, rebooting...'
 +        exit 3010
 +    }
 +    else
 +    {
 +        Write-Log 'No need to reboot.'
 +    }
 +}
 +
 +function Get-InstallerStatus {
 +    $Busy = $true
 +    $lastWriteTimeCBSLos = (Get-Item C:\Windows\Logs\CBS\CBS.log).LastWriteTime
 +    $TimespanOneMinute = New-TimeSpan -Minutes 1
 +    while ($Busy -eq $true)
 +    {
 +        if (((Get-Date) -$lastWriteTimeCBSLos) -gt $TimespanOneMinute) {
 +            $Busy = $false
 +        }
 +        else {
 +            Write-Log 'Waiting for Trusted Installer...'
 +            Start-Sleep -Seconds 10
 +        }
 +    }
 +    
 +}
 +
 +
 +$LogPath = "$env:SystemDrive\tmp\windows-update-opsi.log"
 +$FirstRun = Test-Path -Path $LogPath
 +
 +Write-Log '***** START *****'
 +
 +# Auskommetniert für OPSI-Once-Script 
 +# Get-Timewindow
 +Get-Rebootrequired
 +Get-InstallerStatus
 +
 +Write-Log 'Searching for new Updates...'
 +
 +#GUI bauen
 +[System.Windows.Forms.Application]::EnableVisualStyles()
 +Add-Type -AssemblyName System.Windows.Forms
 +$Form = New-Object system.Windows.Forms.Form
 +$Form.Text = 'Windows-Update-Status'
 +$Form.Width = 430
 +$Form.Height = 100
 +$Form.TopMost = $True
 +$Form.AutoSizeMode = 'GrowAndShrink'
 +$Form.MinimizeBox = $False
 +$Form.MaximizeBox = $False
 +$Form.WindowState = 'Normal'
 +$Form.SizeGripStyle = 'Hide'
 +$Form.ShowInTaskbar = $False
 +$Form.StartPosition = 'CenterScreen'
 +$Font = New-Object System.Drawing.Font('Arial',12)
 +$Form.Font = $Font
 +$Label = New-Object System.Windows.Forms.Label
 +$Label.Text = 'Suche nach Windows Updates...'
 +$Label.AutoSize = $True
 +$Form.Controls.Add($Label)
 +$Form.Show()
 +$Form.Focus()
 +
 +$Session= New-Object -ComObject Microsoft.Update.Session
 +$Searcher= $Session.CreateUpdateSearcher()
 +
 +$SearchResults = $Searcher.Search("IsInstalled=0 and Type='Software'").Updates
 +if ($SearchResults.Count -eq 0 -and $FirstRun -eq $true)
 +{
 +    Write-Log 'No Updates found.'
 +    Write-Log '***** END *****'
 +    $Label.Text = 'Keine neuen Updates gefunden.'
 +    $Form.Refresh()
 +    Start-Sleep -Seconds 5
 +    $Form.Close()
 +    exit 0
 +}
 +
 +if ($SearchResults.Count -eq 0 -and $FirstRun -eq $false)
 +{
 +    Write-Log 'No Updates found, but it is the first time to search for updates. Reboot!'
 +    Write-Log '***** END *****'
 +    $Label.Text = 'Keine Updates gefunden, neuer Versuch...'
 +    $Form.Refresh()
 +    Start-Sleep -Seconds 5
 +    $form.Close()
 +    exit 3010
 +}
 +
 +foreach ($Update in $SearchResults) {
 +    $TotalUpdateSize = $Update.MaxDownloadSize + $TotalUpdateSize
 +    Write-Log "Found KB$($update.KBArticleIDs), Size: $([math]::Round($($update.MaxDownloadSize/1MB),2).ToString('0.00').PadLeft(6)) MB, Title: $($update.Title)"
 +}
 +
 +Write-Log "Summary: $($SearchResults.Count) new Update(s), $($($TotalUpdateSize/1MB).ToString('0.00')) MB to download."
 +$Label.Text = "$($SearchResults.Count) neue Update(s) gefunden."
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +Write-Log 'Starting Download...'
 +$Label.Text = 'Starte Download.'
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +
 +# ProgressBar bauen
 +$ProgressBarSize = New-Object System.Drawing.Size
 +$ProgressBarSize.Width = 400
 +$ProgressBarSize.Height = 20
 +$ProgressBar = New-Object System.Windows.Forms.ProgressBar
 +$ProgressBar.Left = 5
 +$ProgressBar.Top = 35
 +$ProgressBar.Style = 'Continuous'
 +$ProgressBar.Value = 0
 +$ProgressBar.Size = $ProgressBarSize
 +$Form.Controls.Add($ProgressBar)
 +
 +$ProgressInPercent = 0
 +$DownloadCount = 0
 +$DownloadSuccessCounter = 0
 +$DownloadFailedCounter = 0
 +
 +foreach ($DownloadItem in $SearchResults)
 +{
 +    $DownloadCount++
 +    $Downloader = $Session.CreateUpdateDownloader()
 +    $DownloadItems = New-Object -ComObject Microsoft.Update.UpdateColl
 +    $DownloadItems.Add($DownloadItem)
 +    $Downloader.Updates = $DownloadItems
 +    $DownloadResult = $Downloader.Download()
 +    if ($DownloadResult.ResultCode -eq 2) {
 +        $DownloadSuccessCounter++
 +        Write-Log "Successfully downloaded Update $DownloadCount of $($SearchResults.Count), KB$($DownloadItem.KBArticleIDs), Size: $(($DownloadItem.MaxDownloadSize/1MB).ToString('0.00')) MB, Title: $($DownloadItem.Title)"
 +        $ProgressInPercent = ($DownloadCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Download $DownloadCount von $($SearchResults.Count) erfolgreich."
 +        $Form.Refresh()
 +    }
 +    else {
 +        $DownloadFailedCounter++
 +        Write-Log "Failed downloading Update $DownloadCount of $($SearchResults.Count), KB$($DownloadItem.KBArticleIDs), Title: $($DownloadItem.Title)"
 +        $ProgressInPercent = ($DownloadCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Download $DownloadCount von $($SearchResults.Count) fehlgeschlagen."
 +        $Form.Refresh()
 +
 +    }
 +}
 +Write-Log "Summary: Successfully downloaded $DownloadSuccessCounter Updates, failed to download $DownloadFailedCounter Updates."
 +
 +Write-Log 'Starting Install...'
 +$ProgressBar.Value = 0
 +$Label.Text = 'Starte Installation...'
 +$Form.Refresh()
 +
 +$InstallCount = 0
 +$InstallSuccessCounter = 0
 +$InstallFailedCounter = 0
 +foreach ($InstallItem in $SearchResults)
 +{
 +    $InstallCount++
 +    $Installer = $Session.CreateUpdateInstaller()
 +    $InstallerItems = New-Object -ComObject Microsoft.Update.UpdateColl
 +    $InstallerItems.Add($InstallItem)
 +    $Installer.Updates = $InstallerItems
 +    $InstallResult = $Installer.Install()
 +    if ($InstallResult.ResultCode -eq 2) {
 +        $InstallSuccessCounter++
 +        Write-Log "Successfully installed Update $InstallCount of $($SearchResults.Count), KB$($InstallItem.KBArticleIDs), Title: $($InstallItem.Title)"
 +        $ProgressInPercent = ($InstallCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Update $InstallCount von $($SearchResults.Count) erfolgreich installiert."
 +        $Form.Refresh()
 +    }
 +    else {
 +        $InstallFailedCounter++
 +        Write-Log "Failed installing Update $InstallCount of $($SearchResults.Count), KB$($InstallItem.KBArticleIDs), Title: $($InstallItem.Title)"
 +        $ProgressInPercent = ($InstallCount / $($SearchResults.Count))*100
 +        $ProgressBar.Value = $ProgressInPercent
 +        $Label.Text = "Update $InstallCount von $($SearchResults.Count) fehlgeschlagen."
 +        $Form.Refresh()
 +    }
 +}
 +Write-Log "Summary: Successfully installed $InstallSuccessCounter Updates, failed to install $InstallFailedCounter Updates."
 +Write-Log 'Rebooting...'
 +Write-Log '***** END *****'
 +$Label.Text = "$InstallSuccessCounter Updates erfolgreich, $InstallFailedCounter Updates fehlgeschlagen."
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +$Label.Text = 'Neustart des Systems'
 +$Form.Refresh()
 +Start-Sleep -Seconds 5
 +$Form.Close()
 +exit 3010
 +</code>
  
userspace/windows_updates_-_powershell.1488447115.txt.gz · Last modified: 2021/08/23 08:37 (external edit)