-
Notifications
You must be signed in to change notification settings - Fork 126
Expand file tree
/
Copy pathRebootManagement.ps1
More file actions
161 lines (145 loc) · 6.61 KB
/
RebootManagement.ps1
File metadata and controls
161 lines (145 loc) · 6.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<#
.SYNOPSIS
LastBootup
.DESCRIPTION
This script will query the SCCM SQL database for a list of machines that have not been rebooted for more than ten days
.PARAMETER Collection
Name of the collection to query. PowerShell will find the SQL table name from the collection name
.PARAMETER SQLServer
Name of the SQL server that contains the SCCM database
.PARAMETER SQLDatabase
Name of the SCCM SQL database
.PARAMETER DeploymentName
Name of deployment of the SCCM reboot package
.PARAMETER MaxDays
If system has not rebooted for this number of days, then add to $Report
.PARAMETER SQLInstance
Name of the SQL Database
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.142
Created on: 10/22/2019 10:21 AM
Created by: Mick Pletcher
Filename: RebootManagement.ps1
===========================================================================
#>
[CmdletBinding()]
param
(
[ValidateNotNullOrEmpty()]
[string]$Collection,
[ValidateNotNullOrEmpty()]
[string]$SQLServer,
[ValidateNotNullOrEmpty()]
[string]$SQLDatabase,
[ValidateNotNullOrEmpty()]
[string]$DeploymentName,
[ValidateNotNullOrEmpty()]
[int]$MaxDays
)
function Initialize-Reboot {
<#
.SYNOPSIS
Initialize Timed Reboot
.DESCRIPTION
This will change the reboot package from advertised to mandatory in order to initiate the reboot. It will then change package back to advertised once the package has been executed.
.PARAMETER Object
A description of the Object parameter.
.EXAMPLE
PS C:\> Initialize-Reboot
.NOTES
Additional information about the function.
#>
[CmdletBinding()]
param
(
$Object
)
If ((Test-Connection -ComputerName $Object.Name -Quiet) -eq $true) {
#Query the remote system to make sure it has not been rebooted since the LastBootUpTime was updated to SCCM
If ((New-TimeSpan -Start ([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject -Class win32_operatingsystem -ComputerName $Object.Name).LastBootUpTime))).Days -gt $MaxDays) {
#Package and Advertisement IDs of the SCCM package
$Advertisement = Get-WmiObject -Namespace "root\ccm\policy\machine\actualconfig" -Class "CCM_SoftwareDistribution" -ComputerName $Object.Name | Where-Object {$_.PKG_Name -eq $DeploymentName} | Select-Object -Property PKG_PackageID, ADV_AdvertisementID
#Continue to next array item if the advertisement is null, meaning the reboot application was not advertised to the system
If ($Advertisement -ne $null) {
#Schedule IS of the SCCM package deployment
$ScheduleID = Get-WmiObject -Namespace "root\ccm\scheduler" -Class "CCM_Scheduler_History" -ComputerName $Object.Name | Where-Object {
$_.ScheduleID -like "*$($Advertisement.PKG_PackageID)*"
} | Select-Object -ExpandProperty ScheduleID
#Retrieve advertisement policy
$Policy = Get-WmiObject -Namespace "root\ccm\policy\machine\actualconfig" -Class "CCM_SoftwareDistribution" -ComputerName $Object.Name | Where-Object {
$_.PKG_Name -eq $DeploymentName
}
#Change advertisement policy to mandatory so the package can be executed
If ($Policy.ADV_MandatoryAssignments -eq $false) {
$Policy.ADV_MandatoryAssignments = $true
$Policy.Put() | Out-Null
}
#Execute the advertisement
Invoke-WmiMethod -Namespace "root\ccm" -Class "SMS_Client" -Name "TriggerSchedule" -ArgumentList $ScheduleID -ComputerName $Object.Name
#Wait one second to give time for the package to initiate
Start-Sleep -Seconds 1
#Retrieve advertisement policy
$Policy = Get-WmiObject -Namespace "root\ccm\policy\machine\actualconfig" -Class "CCM_SoftwareDistribution" -ComputerName $Object.Name | Where-Object {
$_.PKG_Name -eq $DeploymentName
}
#Remove the mandatory assignment from the package so this is not rerun
If ($Policy.ADV_MandatoryAssignments -eq $true) {
$Policy.ADV_MandatoryAssignments = $false
$Policy.Put() | Out-Null
}
}
}
} else {
Return $null
}
Return $object
}
#Get the table name from the $Collection value
$TableName = 'dbo.' + ((Invoke-Sqlcmd -ServerInstance $SQLServer -Database $SQLDatabase -Query ('SELECT ResultTableName FROM dbo.v_Collections WHERE CollectionName = ' + [char]39 + $Collection + [char]39)).ResultTableName)
#Query active systems in the above table to list the computer name and the last boot up time
$Query = 'SELECT Name, LastBootUpTime0, ClientState FROM dbo.v_GS_OPERATING_SYSTEM INNER JOIN' + [char]32 + $TableName + [char]32 + 'ON dbo.v_GS_OPERATING_SYSTEM.ResourceID =' + [char]32 + $TableName + '.MachineID WHERE ((((DATEDIFF(DAY,LastBootUpTime0,GETDATE())) >' + [char]32 + $MaxDays + ') OR ClientState <> 0) AND LastBootUpTime0 IS NOT NULL)'
#Query SCCM SQL database
$List = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $SQLDatabase -Query $Query
#Create report array to contain list of all systems that have not rebooted for $Threshold days
$Report = @()
#Check if list is null. If so, exit with error code 1 so if script is used in Orchestrator or SMA, it can be set to not proceed with email.
If ($List -ne '') {
#Get list of machines that are exceed number of days allowed without rebooting. This is also used as a report if desired to be emailed.
$List | ForEach-Object {
If ($_.ClientState -ne 0) {
$PendingReboot = $true
} else {
$PendingReboot = $false
}
If ((Test-Connection -ComputerName $_.Name -Count 1 -Quiet) -eq $true) {
$Online = $true
} else {
$Online = $false
}
#Create new object
$object = New-Object -TypeName System.Management.Automation.PSObject
$object | Add-Member -MemberType NoteProperty -Name Name -Value $_.Name
$object | Add-Member -MemberType NoteProperty -Name LastBootUpTime -Value $_.LastBootUpTime0
$object | Add-Member -MemberType NoteProperty -Name PendingReboot -Value $PendingReboot
$object | Add-Member -MemberType NoteProperty -Name Online -Value $Online
If ($object.Online -eq $true) {
$obj = Initialize-Reboot -Object $object
}
#If the reboot was initiated, then add to $Report
If ($obj -ne $null) {
$Report += $obj
}
}
If ($Report -eq $null) {
#This exit code is used for signaling to a link in Orchestrator or Azure Automation to not proceed to the next activity
Write-Host "Null"
Exit 1
} else {
Write-Output $Report | Sort-Object LastBootUpTime, Name
}
} else {
#This exit code is used for signaling to a link in Orchestrator or Azure Automation to not proceed to the next activity
Write-Host "Null"
Exit 1
}