Posted in : Microsoft, System Center Av Stina Perbo Utas Översätt med Google ⟶
7 years ago
Reading SCCM Maintenance Windows is not an easy thing to do from WMI as they are stored as 16 char hex values
To get the schedule hex values simply run the below line, but the result might not be easy to understand
Get-WmiObject -Namespace 'ROOT\ccm\Policy\Machine\RequestedConfig' -Class CCM_ServiceWindow | Select -ExpandProperty Schedules
A server might return the following values.
02C24AC0381A2000 02C24AC0381C2000 02C24AC0381B2000 02C24AC0101E2000 026B3B80601C2001 02C24AC0381D2000 00084AC028592000 00074AC0005F2000
Now, how do we read this? The easiest thing is to run Convert-CMSchedule but that unfortunately only works if the configuration manager console is installed.
Another way to do is to invoke a wmi method from a site server using the SMS_ScheduleMethods class.
None of these are portable, so I created my own function to decode these. The below function returns the same data as Convert-CMSchedule but is free from any module as it converts the hex to a readable format.
The function also accepts valuefrompipeline
PS C:\Windows\system32> Get-WmiObject -Namespace 'ROOT\ccm\Policy\Machine\RequestedConfig' -Class CCM_ServiceWindow | Select -ExpandProperty Schedules | ConvertFrom-CMSchedule | select -first 2 SmsProviderObjectPath : SMS_ST_RecurWeekly Day : 2 DayDuration : 0 ForNumberOfWeeks : 1 HourDuration : 7 IsGMT : False MinuteDuration : 0 StartTime : 2009-05-01 22:00:00 PSComputerName : Server1 SmsProviderObjectPath : SMS_ST_RecurWeekly Day : 2 DayDuration : 0 ForNumberOfWeeks : 1 HourDuration : 7 IsGMT : False MinuteDuration : 0 StartTime : 2013-04-02 22:00:00 PSComputerName : Server2
Function ConvertFrom-CMSchedule { <# .Synopsis Converts CMSchedule hex string to CMScheduleObject .NOTES Name: ConvertFrom-CMSchedule Author: Vikingur Saemundsson Date Created: 2017-04-18 Version History: 2017-04-18 - Vikingur Saemundsson Initial Creation Xenit AB #> [cmdletbinding()] Param( [Parameter( ValueFromPipeline=$true, Mandatory=$True )] $Schedule ) Begin{ } Process{ $Start = $Schedule.Substring(0,8) $Recurrence = $Schedule.Substring(8,8) If($Start -eq '00012000'){ $Type = 'Simple' } Else{ $Type = 'Custom' #Convert to binary string $BStart = [Convert]::ToString([int64]"0x$Start".ToString(),2) #Pad to 32 chars If($BStart.Length -lt 32){0..(31-$BStart.Length) | ForEach-Object{$Bstart = "0$BStart"}} #Collect timedata [String]$StartMinute = [Convert]::ToInt32($BStart.Substring(0,6),2) If($StartMinute.Length -eq 1){$StartMinute = "0$StartMinute"} [String]$StartHour = [Convert]::ToInt32($BStart.Substring(6,5),2) If($StartHour.Length -eq 1){$StartHour = "0$StartHour"} [String]$StartDay = [Convert]::ToInt32($BStart.Substring(11,5),2) If($StartDay.Length -eq 1){$StartDay = "0$StartDay"} [String]$StartMonth = [Convert]::ToInt32($BStart.Substring(16,4),2) If($StartMonth.Length -eq 1){$StartMonth = "0$StartMonth"} [String]$StartYear = [Convert]::ToInt32($BStart.Substring(20,6),2)+1970 $StartString = "$StartYear-$StartMonth-$StartDay $StartHour`:$StartMinute`:00" } #Convert to binary string $BRec = [Convert]::ToString([int64]"0x$Recurrence".ToString(),2) #Pad to 32 chars If($BRec.Length -lt 32){0..(31-$BRec.Length) | ForEach-Object{$BRec = "0$BRec"}} [bool]$GMT = [Convert]::ToInt32($BRec.Substring(31,1),2) $DayDuration = 0 $HourDuration = [Convert]::ToInt32($BRec.Substring(0,5),2) $MinuteDuration = [Convert]::ToInt32($BRec.Substring(5,5),2) If($HourDuration -gt 24){ $h = $HourDuration % 24 $DayDuration = ($HourDuration-$h)/24 $HourDuration = $h } $RecurType = [Convert]::ToInt32($BRec.Substring(10,3),2) Switch($RecurType){ 1{ $path = 'SMS_ST_NonRecurring' ##?? } 2{ $path = 'SMS_ST_RecurInterval' $MinuteSpan = [Convert]::ToInt32($BRec.Substring(13,6),2) $HourSpan = [Convert]::ToInt32($BRec.Substring(19,5),2) $DaySpan = [Convert]::ToInt32($BRec.Substring(24,5),2) $Ret = '#TYPE IResultObject#SMS_ST_RecurInterval "SmsProviderObjectPath","DayDuration","DaySpan","HourDuration","HourSpan","IsGMT","MinuteDuration","MinuteSpan","StartTime","PSComputerName","PSShowComputerName" "SMS_ST_RecurInterval","{0}","{1}","{2}","{3}","{4}","{5}","{6}","1970-02-01 00:00:00","{7}","False"' -f $DayDuration,$DaySpan,$HourDuration,$HourSpan,$GMT,$MinuteDuration,$MinuteSpan,$env:COMPUTERNAME | ConvertFrom-Csv } 3{ $path = 'SMS_ST_RecurWeekly' $Day = [Convert]::ToInt32($BRec.Substring(13,3),2) $ForNumberOfWeeks = [Convert]::ToInt32($BRec.Substring(16,3),2) $ret = '#TYPE IResultObject#SMS_ST_RecurWeekly "SmsProviderObjectPath","Day","DayDuration","ForNumberOfWeeks","HourDuration","IsGMT","MinuteDuration","StartTime","PSComputerName","PSShowComputerName" "SMS_ST_RecurWeekly","{0}","{1}","{2}","{3}","{4}","{5}","{6}","{7}","False"' -f $Day,$DayDuration,$ForNumberOfWeeks,$HourDuration,$GMT,$MinuteDuration,$StartString,$env:COMPUTERNAME | ConvertFrom-Csv } 4{ $path = 'SMS_ST_RecurMonthlyByWeekday' $Day = [Convert]::ToInt32($BRec.Substring(13,3),2) $ForNumberOfMonths = [Convert]::ToInt32($BRec.Substring(16,4),2) $WeekOrder = [Convert]::ToInt32($BRec.Substring(20,3),2) $ret = '#TYPE IResultObject#SMS_ST_RecurMonthlyByWeekday "SmsProviderObjectPath","Day","DayDuration","ForNumberOfMonths","HourDuration","IsGMT","MinuteDuration","StartTime","WeekOrder","PSComputerName","PSShowComputerName" "SMS_ST_RecurMonthlyByWeekday","{0}","{1}","{2}","{3}","{4}","{5}","{6}","{7}","{8}","False"' -f $Day,$DayDuration,$ForNumberOfMonths,$HourDuration,$GMT,$MinuteDuration,$StartString,$WeekOrder,$env:COMPUTERNAME | ConvertFrom-Csv } 5{ $path = 'SMS_ST_RecurMonthlyByDate' $MonthDay = [Convert]::ToInt32($BRec.Substring(13,5),2) $ForNumberOfMonths = [Convert]::ToInt32($BRec.Substring(18,4),2) $Ret = '#TYPE IResultObject#SMS_ST_RecurMonthlyByDate "SmsProviderObjectPath","DayDuration","ForNumberOfMonths","HourDuration","IsGMT","MinuteDuration","MonthDay","StartTime","PSComputerName","PSShowComputerName" "SMS_ST_RecurMonthlyByDate","{0}","{1}","{2}","{3}","{4}","{5}","{6}","{7}","False"' -f $DayDuration,$ForNumberOfMonths,$HourDuration,$GMT,$MinuteDuration,$MonthDay,$StartString,$env:COMPUTERNAME | ConvertFrom-Csv } Default{ Throw "Invalid type" } } $Ret } End{ } }
The script is reverse engineered from https://msdn.microsoft.com/en-us/library/cc143505.aspx
Tags : MaintenanceWindows, PowerShell, SCCM
Personlig rådgivning
Vi erbjuder personlig rådgivning med författaren för 1400 SEK per timme. Anmäl ditt intresse i här så återkommer vi så snart vi kan.
Add comment