Public/Invoke-ComputerMaintenance.ps1
function Invoke-ComputerMaintenance { #Requires -Version 3.0 #Requires -Modules ResourceLocker [CmdletBinding()] Param ( [Parameter(Mandatory)] [string]$ComputerName, [int]$PreventiveLockTimeout = $ModuleWidePreventiveLockTimeout, [System.TimeSpan]$PreventiveLockThreshold = $ModuleWidePreventiveLockThreshold ) $ErrorActionPreference = 'Stop' Write-Debug -Message ('ENTER {0}' -f $MyInvocation.MyCommand.Name) try { Write-Debug -Message ('ENTER TRY {0}' -f $MyInvocation.MyCommand.Name) Write-Debug -Message ('$ComputerName = ''{0}''' -f $ComputerName) Write-Debug -Message ('$PreventiveLockTimeout = {0}' -f $PreventiveLockTimeout) Write-Debug -Message ('$PreventiveLockThreshold: ''{0}''' -f [string]$PreventiveLockThreshold) Write-Debug -Message ('$IsMaintenanceAllowed = Test-MaintenanceAllowed -ComputerName ''{0}''' -f $ComputerName) $IsMaintenanceAllowed = Test-MaintenanceAllowed -ComputerName $ComputerName Write-Debug -Message ('$IsMaintenanceAllowed: ''{0}''' -f $IsMaintenanceAllowed) Write-Debug -Message 'if ($IsMaintenanceAllowed)' if ($IsMaintenanceAllowed) { Write-Debug -Message ('$IsMaintenanceNeeded = Test-MaintenanceNeeded -ComputerName ''{0}''' -f $ComputerName) $IsMaintenanceNeeded = Test-MaintenanceNeeded -ComputerName $ComputerName Write-Debug -Message ('$IsMaintenanceNeeded: ''{0}''' -f $IsMaintenanceNeeded) Write-Debug -Message 'if ($IsMaintenanceNeeded)' if ($IsMaintenanceNeeded) { Write-Debug -Message '$CallerName = Get-LockCallerName' $CallerName = Get-LockCallerName Write-Debug -Message ('$CallerName = ''{0}''' -f $CallerName) Write-Debug -Message ('$HostLock = Lock-HostResource -ComputerName ''{0}'' -CallerName ''{1}'' -Hard' -f $ComputerName, $CallerName) $HostLock = Lock-HostResource -ComputerName $ComputerName -CallerName $CallerName -Hard Write-Debug -Message ('$HostLock: ''{0}''' -f [string]$HostLock) Write-Debug -Message '$InitialDateTime = Get-Date' $InitialDateTime = Get-Date Write-Debug -Message ('$InitialDateTime: ''{0}''' -f [string]$InitialDateTime) do { Write-Debug -Message ('$HostLockedPreventive = Test-HostResourceLock -ComputerName ''{0}'' -Type @(''Generic'', ''File'')' -f $ComputerName) $HostLockedPreventive = Test-HostResourceLock -ComputerName $ComputerName -Type @('Generic', 'File') Write-Debug -Message ('$HostLockedPreventive: ''{0}''' -f [string]$HostLockedPreventive) Write-Debug -Message 'if ($HostLockedPreventive)' if ($HostLockedPreventive) { Write-Debug -Message '$CurrentDateTime = Get-Date' $CurrentDateTime = Get-Date Write-Debug -Message ('$CurrentDateTime: ''{0}''' -f [string]$CurrentDateTime) Write-Debug -Message ('$InitialDateTime: ''{0}''' -f [string]$InitialDateTime) Write-Debug -Message ('$PreventiveLockThreshold: ''{0}''' -f [string]$PreventiveLockThreshold) Write-Debug -Message '$PreventiveLockDateTimeThreshold = $InitialDateTime + $PreventiveLockThreshold' $PreventiveLockDateTimeThreshold = $InitialDateTime + $PreventiveLockThreshold Write-Debug -Message ('$PreventiveLockDateTimeThreshold: ''{0}''' -f [string]$PreventiveLockDateTimeThreshold) Write-Debug -Message 'if ($CurrentDateTime -gt $PreventiveLockDateTimeThreshold)' if ($CurrentDateTime -gt $PreventiveLockDateTimeThreshold) { $Message = ('Computer {0} is locked by other sources for more than {1} already' -f $ComputerName, [string]$PreventiveLockThreshold) $PSCmdlet.ThrowTerminatingError((New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList ((New-Object -TypeName 'System.TimeoutException' -ArgumentList $Message), 'TimeoutException', [System.Management.Automation.ErrorCategory]::OperationTimeout, $null))) } else { Write-Debug -Message ('Start-Sleep -Seconds {0}' -f $PreventiveLockTimeout) Start-Sleep -Seconds $PreventiveLockTimeout } } Write-Debug -Message 'while ($HostLockedPreventive)' } while ($HostLockedPreventive) Write-Debug -Message ('$PreClearVariables = Invoke-CustomScriptBlockCommand -Mode ''PreClear'' -ComputerName ''{0}'' -Variables (Get-Variable | Where-Object -FilterScript {{$_ -is [System.Management.Automation.PSVariable]}})' -f $ComputerName) $PreClearVariables = Invoke-CustomScriptBlockCommand -Mode 'PreClear' -ComputerName $ComputerName -Variables (Get-Variable | Where-Object -FilterScript {$_ -is [System.Management.Automation.PSVariable]}) Write-Debug -Message ('$PreClearVariables: ''{0}''' -f [string]$PreClearVariables) Write-Debug -Message 'if ($PreClearVariables)' if ($PreClearVariables) { foreach ($PreClearVariable in $PreClearVariables) { Write-Debug -Message ('$PreClearVariable: ''{0}''' -f [string]$PreClearVariable) Write-Debug -Message ('Set-Variable -Name ''{0}'' -Value ''{1}''' -f $PreClearVariable.Name, [string]$PreClearVariable.Value) Set-Variable -Name $PreClearVariable.Name -Value $PreClearVariable.Value } } Write-Debug -Message '$DestinationHostLock = $null' $DestinationHostLock = $null Write-Debug -Message ('$ComputerWorkload = Clear-ComputerWorkload -ComputerName {0} -DestinationHostLock {1}' -f $ComputerName, $DestinationHostLock) $ComputerWorkload = Clear-ComputerWorkload -ComputerName $ComputerName -DestinationHostLock ([ref]$DestinationHostLock) Write-Debug -Message ('$ComputerWorkload: ''{0}''' -f [string]$ComputerWorkload) Write-Debug -Message ('$DestinationHostLock: ''{0}''' -f $DestinationHostLock) Write-Debug -Message ('$PostClearVariables = Invoke-CustomScriptBlockCommand -Mode ''PostClear'' -ComputerName ''{0}'' -Variables (Get-Variable | Where-Object -FilterScript {{$_ -is [System.Management.Automation.PSVariable]}})' -f $ComputerName) $PostClearVariables = Invoke-CustomScriptBlockCommand -Mode 'PostClear' -ComputerName $ComputerName -Variables (Get-Variable | Where-Object -FilterScript {$_ -is [System.Management.Automation.PSVariable]}) Write-Debug -Message ('$PostClearVariables: ''{0}''' -f [string]$PostClearVariables) Write-Debug -Message 'if ($PostClearVariables)' if ($PostClearVariables) { foreach ($PostClearVariable in $PostClearVariables) { Write-Debug -Message ('$PostClearVariable: ''{0}''' -f [string]$PostClearVariable) Write-Debug -Message ('Set-Variable -Name ''{0}'' -Value ''{1}''' -f $PostClearVariable.Name, [string]$PostClearVariable.Value) Set-Variable -Name $PostClearVariable.Name -Value $PostClearVariable.Value } } Write-Debug -Message ('Start-Maintenance -ComputerName ''{0}''' -f $ComputerName) Start-Maintenance -ComputerName $ComputerName Write-Debug -Message ('Set-MaintenanceState -ComputerName ''{0}''' -f $ComputerName) Set-MaintenanceState -ComputerName $ComputerName Write-Debug -Message ('$TestComputerResult = Test-Computer -ComputerName ''{0}''' -f $ComputerName) $TestComputerResult = Test-Computer -ComputerName $ComputerName Write-Debug -Message ('$TestComputerResult = ''{0}''' -f $TestComputerResult) Write-Debug -Message 'if ($TestComputerResult)' if ($TestComputerResult) { Write-Debug -Message ('$PreRestoreVariables = Invoke-CustomScriptBlockCommand -Mode ''PreRestore'' -ComputerName ''{0}'' -Variables (Get-Variable | Where-Object -FilterScript {{$_ -is [System.Management.Automation.PSVariable]}})' -f $ComputerName) $PreRestoreVariables = Invoke-CustomScriptBlockCommand -Mode 'PreRestore' -ComputerName $ComputerName -Variables (Get-Variable | Where-Object -FilterScript {$_ -is [System.Management.Automation.PSVariable]}) Write-Debug -Message ('$PreRestoreVariables: ''{0}''' -f [string]$PreRestoreVariables) Write-Debug -Message 'if ($PreRestoreVariables)' if ($PreRestoreVariables) { foreach ($PreRestoreVariable in $PreRestoreVariables) { Write-Debug -Message ('$PreRestoreVariable: ''{0}''' -f [string]$PreRestoreVariable) Write-Debug -Message ('Set-Variable -Name ''{0}'' -Value ''{1}''' -f $PreRestoreVariable.Name, [string]$PreRestoreVariable.Value) Set-Variable -Name $PreRestoreVariable.Name -Value $PreRestoreVariable.Value } } Write-Debug -Message '$ComputerWorkload = $ComputerWorkload | Select-Object -Unique' $ComputerWorkload = $ComputerWorkload | Select-Object -Unique Write-Debug -Message 'if ($ComputerWorkload -or $ComputerWorkload -is [System.Array])' if ($ComputerWorkload -or $ComputerWorkload -is [System.Array]) { Write-Debug -Message ('Restore-ComputerWorkload -ComputerName ''{0}''' -f $ComputerName) Restore-ComputerWorkload -ComputerName $ComputerName -DestinationHostLock ([ref]$DestinationHostLock) } Write-Debug -Message ('$PostRestoreVariables = Invoke-CustomScriptBlockCommand -Mode ''PostRestore'' -ComputerName ''{0}'' -Variables (Get-Variable | Where-Object -FilterScript {{$_ -is [System.Management.Automation.PSVariable]}})' -f $ComputerName) $PostRestoreVariables = Invoke-CustomScriptBlockCommand -Mode 'PostRestore' -ComputerName $ComputerName -Variables (Get-Variable | Where-Object -FilterScript {$_ -is [System.Management.Automation.PSVariable]}) Write-Debug -Message ('$PostRestoreVariables: ''{0}''' -f [string]$PostRestoreVariables) Write-Debug -Message 'if ($PostRestoreVariables)' if ($PostRestoreVariables) { foreach ($PostRestoreVariable in $PostRestoreVariables) { Write-Debug -Message ('$PostRestoreVariable: ''{0}''' -f [string]$PostRestoreVariable) Write-Debug -Message ('Set-Variable -Name ''{0}'' -Value ''{1}''' -f $PostRestoreVariable.Name, [string]$PostRestoreVariable.Value) Set-Variable -Name $PostRestoreVariable.Name -Value $PostRestoreVariable.Value } } } else { $Message = 'Test-Computer ended unsuccessfully against {0}' -f $ComputerName $PSCmdlet.ThrowTerminatingError((New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList ((New-Object -TypeName 'System.SystemException' -ArgumentList $Message), 'SystemException', [System.Management.Automation.ErrorCategory]::InvalidResult, $null))) } } } Write-Debug -Message ('EXIT TRY {0}' -f $MyInvocation.MyCommand.Name) } catch { Write-Debug -Message ('ENTER CATCH {0}' -f $MyInvocation.MyCommand.Name) Write-Debug -Message ('{0}: $PSCmdlet.ThrowTerminatingError($_)' -f $MyInvocation.MyCommand.Name) $PSCmdlet.ThrowTerminatingError($_) Write-Debug -Message ('EXIT CATCH {0}' -f $MyInvocation.MyCommand.Name) } finally { Write-Debug -Message ('ENTER FINALLY {0}' -f $MyInvocation.MyCommand.Name) Write-Debug -Message ('$FinallyVariables = Invoke-CustomScriptBlockCommand -Mode ''Finally'' -ComputerName ''{0}'' -Variables (Get-Variable | Where-Object -FilterScript {{$_ -is [System.Management.Automation.PSVariable]}})' -f $ComputerName) $FinallyVariables = Invoke-CustomScriptBlockCommand -ComputerName $ComputerName -Mode 'Finally' -Variables (Get-Variable | Where-Object -FilterScript {$_ -is [System.Management.Automation.PSVariable]}) Write-Debug -Message ('$FinallyVariables: ''{0}''' -f [string]$FinallyVariables) Write-Debug -Message 'if ($FinallyVariables)' if ($FinallyVariables) { foreach ($FinallyVariable in $FinallyVariables) { Write-Debug -Message ('$FinallyVariable: ''{0}''' -f [string]$FinallyVariable) Write-Debug -Message ('Set-Variable -Name ''{0}'' -Value ''{1}''' -f $FinallyVariable.Name, [string]$ErrorHandlingVariable.Value) Set-Variable -Name $FinallyVariable.Name -Value $FinallyVariable.Value } } Write-Debug -Message 'if ($HostLock)' if ($HostLock) { Write-Debug -Message 'Unlock-Resource -LockObject $HostLock' Unlock-Resource -LockObject $HostLock } Write-Debug -Message 'if ($DestinationHostLock)' if ($DestinationHostLock) { Write-Debug -Message 'Unlock-Resource -LockObject $DestinationHostLock' Unlock-Resource -LockObject $DestinationHostLock } Write-Debug -Message ('EXIT FINALLY {0}' -f $MyInvocation.MyCommand.Name) } Write-Debug -Message ('EXIT {0}' -f $MyInvocation.MyCommand.Name) } |