Modules/Start-SCOMAgentMaintenanceMode.ps1
Function�Start-SCOMAgentMaintenanceMode { <#� .SYNOPSIS� This�function�triggers maintenance mode on the current SCOM agent monitored server. It will prevent to set SCOM management server into maintenance mode.� Limitation: Works only with SCOM 2016. � .PARAMETER��Reason� Defined reason for the maintenance mode .PARAMETER��Comment� Optional parameter which can be set to add a comment. .PARAMETER Duration Minutes to put system into mainteance mode � .EXAMPLE� PS�C:\>�Start-SCOMAgentMaintenanceMode -Reason PlannedHardwareInstallation -Comment "Need to change HW" -Duration 60 #>� [CmdletBinding()]� param�(� [ValidateSet( 'PlannedOther', 'UnplannedOther', 'PlannedHardwareMaintenance', 'UnplannedHardwareMaintenance', 'PlannedHardwareInstallation', 'UnplannedHardwareInstallation', 'PlannedOperatingSystemReconfiguration', 'UnplannedOperatingSystemReconfiguration', 'PlannedApplicationMaintenance', 'UnplannedApplicationMaintenance', 'ApplicationInstallation', 'ApplicationUnresponsive', 'ApplicationUnstable', 'SecurityIssue', 'LossOfNetworkConnectivity' )] [Parameter(Mandatory = $false)]� [string]$Reason = 'PlannedOther',� [Parameter(Mandatory = $false)]� [string]$Comment = 'No comment set', [Parameter(Mandatory = $true)]� [double]$Duration )� Try { $MinimumDurationInMins = 5.0 $ParamSeparator = '|' $CommentSeparator = ':' $ExtraTimeInMinutes = 8.0 $RegistryKey = 'HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\MaintenanceMode' $Valid = $null $Record = $null $Current = [System.Security.Principal.WindowsIdentity]::GetCurrent() $WindowsPrincipal = [System.Security.Principal.WindowsPrincipal]::new($Current) If(!($WindowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator ))) { Write-Warning -Message 'Permission denied. Use elevated permission!' Throw } If(Test-MgmtServer) { Write-Warning -Message 'This command can run only on Agent Machine' Throw } $Now = Get-Date $d = $Now.AddMinutes($Duration) If(!(Check-MMAgent)) { Write-Warning -Message 'SCOM agent is not installed!' Throw } If(($d - $Now).TotalMinutes -lt $MinimumDurationInMins) { Write-Warning -Message 'Minimum duration is 5 minutes!' Throw } If(!([string]::IsNullOrEmpty($Comment))) { $Comment = $Comment.Trim() } $CurrentName = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name If(!(Test-Path -Path $RegistryKey)) { New-Item -Path $RegistryKey -Force Set-ItemProperty -Path $RegistryKey -Name IsValid -Value '-1' Set-ItemProperty -Path $RegistryKey -Name Record -Value '-1' } $Valid = Get-ItemProperty -Path $RegistryKey -Name IsValid $Record = Get-ItemProperty -Path $RegistryKey -Name Record if($Valid.isValid -eq '-1') { Set-ItemProperty -Path $RegistryKey -Name IsValid -Value '' $Valid = $null } If($Record.Record -eq '-1') { Set-ItemProperty -Path $RegistryKey -Name Record -Value '' $Record = $null } If(!([string]::IsNullOrEmpty($Valid.isValid)) -and !([string]::IsNullOrEmpty($Record.Record)) -and ($Valid.isValid -eq '0' -or $Valid.isValid -eq '1')) { [Double]$Min = $Record.Record.Split('|')[0] [DateTime]$SetDate = $Record.Record.Split('|')[3] [DateTime]$Now = Get-Date [Double]$RemainMin = ($SetDate-$Now).Minutes if($RemainMin -gt 0.0) { $Value = [string]::Concat($Duration,$ParamSeparator,$Reason,$ParamSeparator,$CurrentName,$CommentSeparator,$Comment,$ParamSeparator,$Now.ToString()) Set-ItemProperty -Path $RegistryKey -Name Record -Value $Value Set-ItemProperty -Path $RegistryKey -Name IsValid -Value '1' } $TotalMinutes = ($SetDate.AddMinutes($Min + $ExtraTimeInMinutes) -$Now).TotalMinutes If($TotalMinutes -gt 0.0) { if($Valid.isValid -eq '0') { Write-Warning -Message "System is probably in Maintenance Mode. Preferably try after $(($Now.AddMinutes($TotalMinutes)))" } Else { Write-Warning -Message 'Last Maintenance Mode Request pending. Try afterwards.' } return } $Value = [string]::Concat($Duration,$ParamSeparator,$Reason,$ParamSeparator,$CurrentName,$CommentSeparator,$Comment,$ParamSeparator,$Now.ToString()) Set-ItemProperty -Path $RegistryKey -Name Record -Value $Value Set-ItemProperty -Path $RegistryKey -Name IsValid -Value '1' } Else { $Value = [string]::Concat($Duration,$ParamSeparator,$Reason,$ParamSeparator,$CurrentName,$CommentSeparator,$Comment,$ParamSeparator,$Now.ToString()) Set-ItemProperty -Path $RegistryKey -Name Record -Value $Value Set-ItemProperty -Path $RegistryKey -Name IsValid -Value '1' } } Catch { Write-Warning -Message 'Error!' } } |