diff --git a/ConfigMgrClientHealth.ps1 b/ConfigMgrClientHealth.ps1 index 8948f5d..688852b 100644 --- a/ConfigMgrClientHealth.ps1 +++ b/ConfigMgrClientHealth.ps1 @@ -27,6 +27,7 @@ * ConfigMgr Client Update Handler is working correctly with registry.pol * Windows Update Agent not working correctly, causing client not to receive patches. * Windows Update Agent missing patches that fixes known bugs. + * System drive less then x% freespace then cleanup using cleanmgr.exe .NOTES You should run this with at least local administrator rights. It is recommended to run this script under the SYSTEM context. @@ -39,13 +40,13 @@ Full documentation: https://www.andersrodland.com/configmgr-client-health/ #> -[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] +[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "Medium")] param( - [Parameter(HelpMessage='Path to XML Configuration File')] - [ValidateScript({Test-Path -Path $_ -PathType Leaf})] + [Parameter(HelpMessage = 'Path to XML Configuration File')] + [ValidateScript( { Test-Path -Path $_ -PathType Leaf })] [ValidatePattern('.xml$')] [string]$Config, - [Parameter(HelpMessage='URI to ConfigMgr Client Health Webservice')] + [Parameter(HelpMessage = 'URI to ConfigMgr Client Health Webservice')] [string]$Webservice ) @@ -56,7 +57,7 @@ Begin { $global:ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition #If no config file was passed in, use the default. - If ((!$Config) -and ($Webservice -eq $null)) {$Config = Join-Path ($global:ScriptPath) "Config.xml"} + If ((!$Config) -and ($Webservice -eq $null)) { $Config = Join-Path ($global:ScriptPath) "Config.xml" } Write-Verbose "Script version: $Version" Write-Verbose "PowerShell version: $PowerShellVersion" @@ -67,7 +68,7 @@ Begin { Test the validity of an XML file #> [CmdletBinding()] - param ([parameter(mandatory=$true)][ValidateNotNullorEmpty()][string]$xmlFilePath) + param ([parameter(mandatory = $true)][ValidateNotNullorEmpty()][string]$xmlFilePath) # Check the file exists if (!(Test-Path -Path $xmlFilePath)) { throw "$xmlFilePath is not valid. Please provide a valid path to the .xml config file" } # Check for Load or Parse errors when loading the XML file @@ -111,12 +112,12 @@ Begin { # Import BitsTransfer Module (Does not work on PowerShell Core (6), disable check if module failes to import.) $BitsCheckEnabled = $false if (Get-Module -ListAvailable -Name BitsTransfer) { - try { - Import-Module BitsTransfer -ErrorAction stop - $BitsCheckEnabled = $true - } - catch { $BitsCheckEnabled = $false } - } + try { + Import-Module BitsTransfer -ErrorAction stop + $BitsCheckEnabled = $true + } + catch { $BitsCheckEnabled = $false } + } #region functions Function Get-DateTime { @@ -132,7 +133,7 @@ Begin { # Converts a DateTime object to UTC time. Function Get-UTCTime { - param([Parameter(Mandatory=$true)][DateTime]$DateTime) + param([Parameter(Mandatory = $true)][DateTime]$DateTime) $obj = $DateTime.ToUniversalTime() Write-Output $obj } @@ -148,7 +149,7 @@ Begin { # Update-WebService use ClientHealth Webservice to update database. RESTful API. Function Update-Webservice { - Param([Parameter(Mandatory=$true)][String]$URI, $Log) + Param([Parameter(Mandatory = $true)][String]$URI, $Log) $Hostname = Get-Hostname $Obj = $Log | ConvertTo-Json @@ -174,13 +175,13 @@ Begin { # Retrieve configuration from SQL using webserivce Function Get-ConfigFromWebservice { Param( - [Parameter(Mandatory=$true)][String]$URI, - [Parameter(Mandatory=$false)][String]$ProfileID - ) + [Parameter(Mandatory = $true)][String]$URI, + [Parameter(Mandatory = $false)][String]$ProfileID + ) $URI = $URI + "/ConfigurationProfile" #Write-Host "ProfileID = $ProfileID" - if ($ProfileID -ge 0) { $URI = $URI + "/$ProfileID"} + if ($ProfileID -ge 0) { $URI = $URI + "/$ProfileID" } Write-Verbose "Retrieving configuration from webservice. URI: $URI" try { @@ -196,13 +197,13 @@ Begin { Function Get-ConfigClientInstallPropertiesFromWebService { Param( - [Parameter(Mandatory=$true)][String]$URI, - [Parameter(Mandatory=$true)][String]$ProfileID - ) + [Parameter(Mandatory = $true)][String]$URI, + [Parameter(Mandatory = $true)][String]$ProfileID + ) - $URI = $URI + "/ClientInstallProperties" + $URI = $URI + "/ClientInstallProperties" - Write-Verbose "Retrieving client install properties from webservice" + Write-Verbose "Retrieving client install properties from webservice" try { $CIP = Invoke-RestMethod -Uri $URI } @@ -211,7 +212,7 @@ Begin { Exit 1 } - $string = $CIP | Where-Object {$_.profileId -eq $ProfileID} | Select-Object -ExpandProperty cmd + $string = $CIP | Where-Object { $_.profileId -eq $ProfileID } | Select-Object -ExpandProperty cmd $obj = "" foreach ($i in $string) { @@ -219,19 +220,19 @@ Begin { } # Remove the trailing space from the last parameter caused by the foreach loop - $obj = $obj.Substring(0,$obj.Length-1) + $obj = $obj.Substring(0, $obj.Length - 1) Write-Output $Obj } Function Get-ConfigServicesFromWebservice { Param( - [Parameter(Mandatory=$true)][String]$URI, - [Parameter(Mandatory=$true)][String]$ProfileID - ) + [Parameter(Mandatory = $true)][String]$URI, + [Parameter(Mandatory = $true)][String]$ProfileID + ) - $URI = $URI + "/ConfigurationProfileServices" + $URI = $URI + "/ConfigurationProfileServices" - Write-Verbose "Retrieving client install properties from webservice" + Write-Verbose "Retrieving client install properties from webservice" try { $CS = Invoke-RestMethod -Uri $URI } @@ -240,7 +241,7 @@ Begin { Exit 1 } - $obj = $CS | Where-Object {$_.profileId -eq $ProfileID} | Select-Object Name, StartupType, State, Uptime + $obj = $CS | Where-Object { $_.profileId -eq $ProfileID } | Select-Object Name, StartupType, State, Uptime @@ -257,16 +258,16 @@ Begin { } Function Get-ServiceUpTime { - param([Parameter(Mandatory=$true)]$Name) + param([Parameter(Mandatory = $true)]$Name) - Try{$ServiceDisplayName = (Get-Service $Name).DisplayName} - Catch{ + Try { $ServiceDisplayName = (Get-Service $Name).DisplayName } + Catch { Write-Warning "The '$($Name)' service could not be found." Return } #First try and get the service start time based on the last start event message in the system log. - Try{ + Try { [datetime]$ServiceStartTime = (Get-EventLog -LogName System -Source "Service Control Manager" -EntryType Information -Message "*$($ServiceDisplayName)*running*" -Newest 1).TimeGenerated Return (New-TimeSpan -Start $ServiceStartTime -End (Get-Date)).Days } @@ -275,7 +276,7 @@ Begin { } #If the event log doesn't contain a start event then use the start time of the service's process. Since processes can be shared this is less reliable. - Try{ + Try { if ($PowerShellVersion -ge 6) { $ServiceProcessID = (Get-CimInstance Win32_Service -Filter "Name='$($Name)'").ProcessID } else { $ServiceProcessID = (Get-WMIObject -Class Win32_Service -Filter "Name='$($Name)'").ProcessID } @@ -283,7 +284,7 @@ Begin { Return (New-TimeSpan -Start $ServiceStartTime -End (Get-Date)).Days } - Catch{ + Catch { Write-Warning "Could not get the uptime time for the '$($Name)' service. Returning max value." Return [int]::MaxValue } @@ -292,8 +293,8 @@ Begin { #Loop backwards through a Configuration Manager log file looking for the latest matching message after the start time. Function Search-CMLogFile { Param( - [Parameter(Mandatory=$true)]$LogFile, - [Parameter(Mandatory=$true)][String[]]$SearchStrings, + [Parameter(Mandatory = $true)]$LogFile, + [Parameter(Mandatory = $true)][String[]]$SearchStrings, [datetime]$StartTime = [datetime]::MinValue ) @@ -301,17 +302,17 @@ Begin { $LogData = Get-Content $LogFile #Loop backwards through the log file. - :loop for ($i=($LogData.Count - 1);$i -ge 0; $i--) { + :loop for ($i = ($LogData.Count - 1); $i -ge 0; $i--) { #Parse the log line into its parts. - try{ + try { $LogData[$i] -match '\<\!\[LOG\[(?.*)?\]LOG\]\!\>\.+)(?[+|-])(?\d{2,3})\"\s+date=\"(?.+)?\"\s+component=\"(?.+)?\"\s+context="(?.*)?\"\s+type=\"(?\d)?\"\s+thread=\"(?\d+)?\"\s+file=\"(?.+)?\"\>' | Out-Null - $LogTime = [datetime]::ParseExact($("$($matches.date) $($matches.time)"),"MM-dd-yyyy HH:mm:ss.fff", $null) + $LogTime = [datetime]::ParseExact($("$($matches.date) $($matches.time)"), "MM-dd-yyyy HH:mm:ss.fff", $null) $LogMessage = $matches.message } - catch{ + catch { Write-Warning "Could not parse the line $($i) in '$($LogFile)': $($LogData[$i])" - continue + continue } #If we have gone beyond the start time then stop searching. @@ -321,11 +322,11 @@ Begin { } #Loop through each search string looking for a match. - ForEach($String in $SearchStrings){ + ForEach ($String in $SearchStrings) { If ($LogMessage -match $String) { - Write-Output $LogData[$i] - break loop - } + Write-Output $LogData[$i] + break loop + } } } @@ -339,7 +340,7 @@ Begin { } Function Out-LogFile { - Param([Parameter(Mandatory=$false)][xml]$Xml, $Text, $Mode) + Param([Parameter(Mandatory = $false)][xml]$Xml, $Text, $Mode) if ($Mode -like "Local") { Test-LocalLogging @@ -350,7 +351,7 @@ Begin { if ($mode -like "ClientInstall" ) { $text = "ConfigMgr Client installation failed. Agent not detected 10 minutes after triggering installation." } - $obj = '[' +(Get-DateTime) +'] '+$text + $obj = '[' + (Get-DateTime) + '] ' + $text $obj | Out-File -Encoding utf8 -Append $logFile } @@ -362,10 +363,10 @@ Begin { # Handles different OS languages $OSArchitecture = ($OS.OSArchitecture -replace ('([^0-9])(\.*)', '')) + '-Bit' switch -Wildcard ($OS.Caption) { - "*Embedded*" {$OSName = "Windows 7 " + $OSArchitecture} - "*Windows 7*" {$OSName = "Windows 7 " + $OSArchitecture} - "*Windows 8.1*" {$OSName = "Windows 8.1 " + $OSArchitecture} - "*Windows 10*" {$OSName = "Windows 10 " + $OSArchitecture} + "*Embedded*" { $OSName = "Windows 7 " + $OSArchitecture } + "*Windows 7*" { $OSName = "Windows 7 " + $OSArchitecture } + "*Windows 8.1*" { $OSName = "Windows 8.1 " + $OSArchitecture } + "*Windows 10*" { $OSName = "Windows 10 " + $OSArchitecture } "*Server 2008*" { if ($OS.Caption -like "*R2*") { $OSName = "Windows Server 2008 R2 " + $OSArchitecture } else { $OSName = "Windows Server 2008 " + $OSArchitecture } @@ -387,19 +388,19 @@ Begin { if ($OSName -like "*Windows 10*") { $build = Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber switch ($build) { - 10240 {$OSName = $OSName + " 1507"} - 10586 {$OSName = $OSName + " 1511"} - 14393 {$OSName = $OSName + " 1607"} - 15063 {$OSName = $OSName + " 1703"} - 16299 {$OSName = $OSName + " 1709"} - 17134 {$OSName = $OSName + " 1803"} - 17763 {$OSName = $OSName + " 1809"} - default {$OSName = $OSName + " Insider Preview"} + 10240 { $OSName = $OSName + " 1507" } + 10586 { $OSName = $OSName + " 1511" } + 14393 { $OSName = $OSName + " 1607" } + 15063 { $OSName = $OSName + " 1703" } + 16299 { $OSName = $OSName + " 1709" } + 17134 { $OSName = $OSName + " 1803" } + 17763 { $OSName = $OSName + " 1809" } + default { $OSName = $OSName + " Insider Preview" } } } $Updates = $UpdateShare + "\" + $OSName + "\" - $obj = New-Object PSObject @{} + $obj = New-Object PSObject @{ } If ((Test-Path $Updates) -eq $true) { $regex = "\b(?!(KB)+(\d+)\b)\w+" $hotfixes = (Get-ChildItem $Updates | Select-Object -ExpandProperty Name) @@ -408,7 +409,7 @@ Begin { foreach ($hotfix in $hotfixes) { $kb = $hotfix -replace $regex -replace "\." -replace "-" - if ($installedUpdates -like $kb) {} + if ($installedUpdates -like $kb) { } else { $obj.Add('Hotfix', $hotfix) } } } @@ -417,8 +418,8 @@ Begin { Function Get-RegistryValue { param ( - [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Path, - [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Name + [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Path, + [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Name ) Return (Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue).$Name @@ -426,14 +427,14 @@ Begin { Function Set-RegistryValue { param ( - [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Path, - [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Name, - [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Value, - [ValidateSet("String","ExpandString","Binary","DWord","MultiString","Qword")]$ProperyType="String" + [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Path, + [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Name, + [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Value, + [ValidateSet("String", "ExpandString", "Binary", "DWord", "MultiString", "Qword")]$ProperyType = "String" ) #Make sure the key exists - If (!(Test-Path $Path)){ + If (!(Test-Path $Path)) { New-Item $Path -Force | Out-Null } @@ -468,7 +469,7 @@ Begin { #if ($PowerShellVersion -ge 6) { $obj = (Get-CimInstance -Namespace "ROOT\CCM\SoftMgmtAgent" -Class CacheConfig -ErrorAction SilentlyContinue).Size } #else { $obj = (Get-WmiObject -Namespace "ROOT\CCM\SoftMgmtAgent" -Class CacheConfig -ErrorAction SilentlyContinue).Size } } - catch { $obj = 0} + catch { $obj = 0 } finally { if ($null -eq $obj) { $obj = 0 } Write-Output $obj @@ -592,7 +593,7 @@ Begin { } function Test-CCMCertificateError { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) # More checks to come $logdir = Get-CCMLogDirectory $logFile1 = "$logdir\ClientIDManagerStartup.log" @@ -647,7 +648,7 @@ Begin { Function Test-BITS { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) if ($BitsCheckEnabled -eq $true) { $Errors = Get-BitsTransfer -AllUsers | Where-Object { ($_.JobState -like "TransientError") -or ($_.JobState -like "Transient_Error") -or ($_.JobState -like "Error") } @@ -687,44 +688,44 @@ Begin { } - Function Test-ClientSettingsConfiguration { - Param([Parameter(Mandatory=$true)]$Log) + Function Test-ClientSettingsConfiguration { + Param([Parameter(Mandatory = $true)]$Log) - $ClientSettingsConfig = @(Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig -ErrorAction SilentlyContinue | Where {$_.PolicySource -eq "CcmTaskSequence"}) + $ClientSettingsConfig = @(Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig -ErrorAction SilentlyContinue | Where { $_.PolicySource -eq "CcmTaskSequence" }) - if ($ClientSettingsConfig.Count -gt 0) { + if ($ClientSettingsConfig.Count -gt 0) { - $fix = (Get-XMLConfigClientSettingsCheckFix).ToLower() + $fix = (Get-XMLConfigClientSettingsCheckFix).ToLower() - if ($fix -eq "true") { - $text = "ClientSettings: Error. Remediating" - DO { - Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig | Where {$_.PolicySource -eq "CcmTaskSequence"} | Select -first 1000 | % {Remove-WmiObject -InputObject $_} - } Until (!(Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig | Where {$_.PolicySource -eq "CcmTaskSequence"} | Select -first 1)) - $log.ClientSettings = 'Remediated' - $obj = $true - } - else { - $text = "ClientSettings: Error. Monitor only" - $log.ClientSettings = 'Error' - $obj = $false - } - } + if ($fix -eq "true") { + $text = "ClientSettings: Error. Remediating" + DO { + Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig | Where { $_.PolicySource -eq "CcmTaskSequence" } | Select -first 1000 | % { Remove-WmiObject -InputObject $_ } + } Until (!(Get-WmiObject -Namespace "root\ccm\Policy\DefaultMachine\RequestedConfig" -Class CCM_ClientAgentConfig | Where { $_.PolicySource -eq "CcmTaskSequence" } | Select -first 1)) + $log.ClientSettings = 'Remediated' + $obj = $true + } + else { + $text = "ClientSettings: Error. Monitor only" + $log.ClientSettings = 'Error' + $obj = $false + } + } - else { - $text = "ClientSettings: OK" - $log.ClientSettings = 'OK' - $Obj = $false - } - Write-Host $text - #Write-Output $Obj + else { + $text = "ClientSettings: OK" + $log.ClientSettings = 'OK' + $Obj = $false + } + Write-Host $text + #Write-Output $Obj } Function New-ClientInstalledReason { Param( - [Parameter(Mandatory=$true)]$Message, - [Parameter(Mandatory=$true)]$Log - ) + [Parameter(Mandatory = $true)]$Message, + [Parameter(Mandatory = $true)]$Log + ) if ($null -eq $log.ClientInstalledReason) { $log.ClientInstalledReason = $Message } else { $log.ClientInstalledReason += " $Message" } @@ -733,10 +734,10 @@ Begin { function Get-PendingReboot { $result = @{ - CBSRebootPending =$false + CBSRebootPending = $false WindowsUpdateRebootRequired = $false - FileRenamePending = $false - SCCMRebootPending = $false + FileRenamePending = $false + SCCMRebootPending = $false } #Check CBS Registry @@ -749,19 +750,17 @@ Begin { #Check PendingFileRenameOperations $prop = Get-ItemProperty 'HKLM:SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue - if ($null -ne $prop) - { + if ($null -ne $prop) { #PendingFileRenameOperations is not *must* to reboot? #$result.FileRenamePending = $true } - try - { + try { $util = [wmiclass]'\\.\root\ccm\clientsdk:CCM_ClientUtilities' $status = $util.DetermineIfRebootPending() - if(($null -ne $status) -and $status.RebootPending){ $result.SCCMRebootPending = $true } + if (($null -ne $status) -and $status.RebootPending) { $result.SCCMRebootPending = $true } } - catch{} + catch { } #Return Reboot required if ($result.ContainsValue($true)) { @@ -786,10 +785,10 @@ Begin { Function Get-OSDiskFreeSpace { - if ($PowerShellVersion -ge 6) { $driveC = Get-CimInstance -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object FreeSpace, Size } - else { $driveC = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object FreeSpace, Size } + if ($PowerShellVersion -ge 6) { $driveC = Get-CimInstance -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object FreeSpace, Size } + else { $driveC = Get-WmiObject -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object FreeSpace, Size } $freeSpace = (($driveC.FreeSpace / $driveC.Size) * 100) - Write-Output ([math]::Round($freeSpace,2)) + Write-Output ([math]::Round($freeSpace, 2)) } Function Get-Computername { @@ -806,7 +805,7 @@ Begin { } Function Get-LastInstalledPatches { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) # Reading date from Windows Update COM object. $Session = New-Object -ComObject Microsoft.Update.Session $Searcher = $Session.CreateUpdateSearcher() @@ -844,7 +843,7 @@ Begin { ($_.ClientApplicationID -eq 'UpdateOrchestrator' -or $_.ClientApplicationID -eq 'ccmexec') -and ($_.Title -notmatch "Definition Update") } | Select-Object -ExpandProperty Date | Measure-Latest } - } + } # Reading date from PowerShell Get-Hotfix #$now = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") @@ -852,8 +851,10 @@ Begin { #$Hotfix = Get-Hotfix | Select-Object -ExpandProperty InstalledOn -ErrorAction SilentlyContinue - if ($PowerShellVersion -ge 6) { $Hotfix = Get-CimInstance -ClassName Win32_QuickFixEngineering | Select-Object @{Name="InstalledOn";Expression={[DateTime]::Parse($_.InstalledOn,$([System.Globalization.CultureInfo]::GetCultureInfo("en-US")))}} } - else { $Hotfix = Get-Hotfix | Select-Object @{l="InstalledOn";e={[DateTime]::Parse($_.psbase.properties["installedon"].value,$([System.Globalization.CultureInfo]::GetCultureInfo("en-US")))}} } + if ($PowerShellVersion -ge 6) { $Hotfix = Get-CimInstance -ClassName Win32_QuickFixEngineering | Select-Object @{Name = "InstalledOn"; Expression = { [DateTime]::Parse($_.InstalledOn, $([System.Globalization.CultureInfo]::GetCultureInfo("en-US"))) } } + } + else { $Hotfix = Get-Hotfix | Select-Object @{l = "InstalledOn"; e = { [DateTime]::Parse($_.psbase.properties["installedon"].value, $([System.Globalization.CultureInfo]::GetCultureInfo("en-US"))) } } + } $Hotfix = $Hotfix | Select-Object -ExpandProperty InstalledOn @@ -872,40 +873,40 @@ Begin { } Function Test-LogFileHistory { - Param([Parameter(Mandatory=$true)]$Logfile) + Param([Parameter(Mandatory = $true)]$Logfile) $startString = '<--- ConfigMgr Client Health Check starting --->' $content = '' # Handle the network share log file - if (Test-Path $logfile -ErrorAction SilentlyContinue) { $content = Get-Content $logfile -ErrorAction SilentlyContinue } - else { return } + if (Test-Path $logfile -ErrorAction SilentlyContinue) { $content = Get-Content $logfile -ErrorAction SilentlyContinue } + else { return } $maxHistory = Get-XMLConfigLoggingMaxHistory - $startCount = [regex]::matches($content,$startString).count + $startCount = [regex]::matches($content, $startString).count # Delete logfile if more start and stop entries than max history if ($startCount -ge $maxHistory) { Remove-Item $logfile -Force } } Function Test-DNSConfiguration { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) #$dnsdomain = (Get-WmiObject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'").DNSDomain $fqdn = [System.Net.Dns]::GetHostEntry([string]"localhost").HostName - if ($PowerShellVersion -ge 6) { $localIPs = Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -Match "True"} | Select-Object -ExpandProperty IPAddress } - else { $localIPs = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -Match "True"} | Select-Object -ExpandProperty IPAddress } + if ($PowerShellVersion -ge 6) { $localIPs = Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -Match "True" } | Select-Object -ExpandProperty IPAddress } + else { $localIPs = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -Match "True" } | Select-Object -ExpandProperty IPAddress } $dnscheck = [System.Net.DNS]::GetHostByName($fqdn) $OSName = Get-OperatingSystem if (($OSName -notlike "*Windows 7*") -and ($OSName -notlike "*Server 2008*")) { # This method is supported on Windows 8 / Server 2012 and higher. More acurate than using .NET object method try { - $ActiveAdapters = (get-netadapter | Where-Object {$_.Status -like "Up"}).Name - $dnsServers = Get-DnsClientServerAddress | Where-Object {$ActiveAdapters -contains $_.InterfaceAlias} | Where-Object {$_.AddressFamily -eq 2} | Select-Object -ExpandProperty ServerAddresses + $ActiveAdapters = (get-netadapter | Where-Object { $_.Status -like "Up" }).Name + $dnsServers = Get-DnsClientServerAddress | Where-Object { $ActiveAdapters -contains $_.InterfaceAlias } | Where-Object { $_.AddressFamily -eq 2 } | Select-Object -ExpandProperty ServerAddresses $dnsAddressList = Resolve-DnsName -Name $fqdn -Server ($dnsServers | Select-Object -First 1) -Type A -DnsOnly | Select-Object -ExpandProperty IPAddress } catch { # Fallback to depreciated method $dnsAddressList = $dnscheck.AddressList | Select-Object -ExpandProperty IPAddressToString - $dnsAddressList = $dnsAddressList -replace("%(.*)", "") + $dnsAddressList = $dnsAddressList -replace ("%(.*)", "") } } @@ -914,7 +915,7 @@ Begin { # For Windows 7 only $dnsAddressList = $dnscheck.AddressList | Select-Object -ExpandProperty IPAddressToString - $dnsAddressList = $dnsAddressList -replace("%(.*)", "") + $dnsAddressList = $dnsAddressList -replace ("%(.*)", "") } $dnsFail = '' @@ -929,15 +930,15 @@ Begin { #Write-Host "Testing if IP address: $dnsIP published in DNS exist in local IP configuration." ##if ($dnsIP -notin $localIPs) { ## Requires PowerShell 3. Works fine :( if ($localIPs -notcontains $dnsIP) { - $dnsFail += "IP '$dnsIP' in DNS record do not exist locally`n" - $logFail += "$dnsIP " - $obj = $false + $dnsFail += "IP '$dnsIP' in DNS record do not exist locally`n" + $logFail += "$dnsIP " + $obj = $false } } } else { $hn = $dnscheck.HostName - $dnsFail = 'DNS name: ' +$hn + ' local fqdn: ' +$fqdn + ' DNS IPs: ' +$dnsAddressList + ' Local IPs: ' + $localIPs + $dnsFail = 'DNS name: ' + $hn + ' local fqdn: ' + $fqdn + ' DNS IPs: ' + $dnsAddressList + ' Local IPs: ' + $localIPs $obj = $false Write-Host $dnsFail } @@ -949,7 +950,7 @@ Begin { $fix = (Get-XMLConfigDNSFix).ToLower() if ($fix -eq "true") { $text = 'DNS Check: FAILED. IP address published in DNS do not match IP address on local machine. Trying to resolve by registerting with DNS server' - if ($PowerShellVersion -ge 4) { Register-DnsClient | out-null } + if ($PowerShellVersion -ge 4) { Register-DnsClient | out-null } else { ipconfig /registerdns | out-null } Write-Host $text $log.DNS = $logFail @@ -983,12 +984,12 @@ Begin { $correctValue = '%USERPROFILE%\AppData\Roaming' $currentValue = (Get-Item 'HKU:\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\').GetValue('AppData', $null, 'DoNotExpandEnvironmentNames') - # Only fix if the value is wrong - if ($currentValue -ne $correctValue) { Set-ItemProperty -Path 'HKU:\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\' -Name 'AppData' -Value $correctValue } + # Only fix if the value is wrong + if ($currentValue -ne $correctValue) { Set-ItemProperty -Path 'HKU:\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\' -Name 'AppData' -Value $correctValue } } Function Test-Update { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) #if (($Xml.Configuration.Option | Where-Object {$_.Name -like 'Updates'} | Select-Object -ExpandProperty 'Enable') -like 'True') { @@ -1005,14 +1006,14 @@ Begin { if ($OSName -like "*Windows 10*") { $build = Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber switch ($build) { - 10240 {$OSName = $OSName + " 1507"} - 10586 {$OSName = $OSName + " 1511"} - 14393 {$OSName = $OSName + " 1607"} - 15063 {$OSName = $OSName + " 1703"} - 16299 {$OSName = $OSName + " 1709"} - 17134 {$OSName = $OSName + " 1803"} - 17763 {$OSName = $OSName + " 1809"} - default {$OSName = $OSName + " Insider Preview"} + 10240 { $OSName = $OSName + " 1507" } + 10586 { $OSName = $OSName + " 1511" } + 14393 { $OSName = $OSName + " 1607" } + 15063 { $OSName = $OSName + " 1703" } + 16299 { $OSName = $OSName + " 1709" } + 17134 { $OSName = $OSName + " 1803" } + 17763 { $OSName = $OSName + " 1809" } + default { $OSName = $OSName + " Insider Preview" } } } @@ -1034,7 +1035,7 @@ Begin { else { $logEntry = $null - $regex = '\b(?!(KB)+(\d+)\b)\w+' + $regex = '\b(?!(KB)+(\d+)\b)\w+' foreach ($hotfix in $hotfixes) { $kb = $hotfix -replace $regex -replace "\." -replace "-" if ($installedUpdates -contains $kb) { @@ -1081,7 +1082,7 @@ Begin { } Function Test-ConfigMgrClient { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) # Check if the SCCM Agent is installed or not. # If installed, perform tests to decide if reinstall is needed or not. @@ -1095,12 +1096,12 @@ Begin { # We test that the local database files exists. Less than 7 means the client is horrible broken and requires reinstall. $LocalDBFilesPresent = Test-CcmSDF if ($LocalDBFilesPresent -eq $False) { - New-ClientInstalledReason -Log $Log -Message "ConfigMgr Client database files missing." - Write-Host "ConfigMgr Client database files missing. Reinstalling..." - # Add /ForceInstall to Client Install Properties to ensure the client is uninstalled before we install client again. - #if (-NOT ($clientInstallProperties -like "*/forceinstall*")) { $clientInstallProperties = $clientInstallProperties + " /forceinstall" } - $Reinstall = $true - $Uninstall = $true + New-ClientInstalledReason -Log $Log -Message "ConfigMgr Client database files missing." + Write-Host "ConfigMgr Client database files missing. Reinstalling..." + # Add /ForceInstall to Client Install Properties to ensure the client is uninstalled before we install client again. + #if (-NOT ($clientInstallProperties -like "*/forceinstall*")) { $clientInstallProperties = $clientInstallProperties + " /forceinstall" } + $Reinstall = $true + $Uninstall = $true } # Only test CM client local DB if this check is enabled @@ -1158,13 +1159,13 @@ Begin { #Start-Sleep 600 # Test again if agent is installed - if (Get-Service -Name ccmexec -ErrorAction SilentlyContinue) {} - else { Out-LogFile -Mode "ClientInstall"} + if (Get-Service -Name ccmexec -ErrorAction SilentlyContinue) { } + else { Out-LogFile -Mode "ClientInstall" } } } Function Test-ClientCacheSize { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $ClientCacheSize = Get-XMLConfigClientCache if ($PowerShellVersion -ge 6) { $Cache = Get-CimInstance -Namespace "ROOT\CCM\SoftMgmtAgent" -Class CacheConfig } else { $Cache = Get-WmiObject -Namespace "ROOT\CCM\SoftMgmtAgent" -Class CacheConfig } @@ -1177,8 +1178,8 @@ Begin { $num = $ClientCacheSize -replace '%' $num = ($num / 100) # TotalDiskSpace in Byte - if ($PowerShellVersion -ge 6) { $TotalDiskSpace = (Get-CimInstance -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object -ExpandProperty Size) } - else { $TotalDiskSpace = (Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object -ExpandProperty Size) } + if ($PowerShellVersion -ge 6) { $TotalDiskSpace = (Get-CimInstance -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object -ExpandProperty Size) } + else { $TotalDiskSpace = (Get-WmiObject -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object -ExpandProperty Size) } $ClientCacheSize = ([math]::Round(($TotalDiskSpace * $num) / 1048576)) } else { $type = 'fixed' } @@ -1192,7 +1193,7 @@ Begin { else { switch ($type) { - 'fixed' {$text = "ConfigMgr Client Cache Size: $CurrentCache. Expected: $ClientCacheSize. Redmediating."} + 'fixed' { $text = "ConfigMgr Client Cache Size: $CurrentCache. Expected: $ClientCacheSize. Redmediating." } 'percentage' { $percent = Get-XMLConfigClientCache if ($ClientCacheSize -gt "99999") { $ClientCacheSize = "99999" } @@ -1211,7 +1212,7 @@ Begin { } Function Test-ClientVersion { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $ClientVersion = Get-XMLConfigClientVersion [String]$ClientAutoUpgrade = Get-XMLConfigClientAutoUpgrade $ClientAutoUpgrade = $ClientAutoUpgrade.ToLower() @@ -1219,17 +1220,17 @@ Begin { $log.ClientVersion = $installedVersion if ($installedVersion -ge $ClientVersion) { - $text = 'ConfigMgr Client version is: ' +$installedVersion + ': OK' + $text = 'ConfigMgr Client version is: ' + $installedVersion + ': OK' Write-Output $text $obj = $false } elseif ($ClientAutoUpgrade -like 'true') { - $text = 'ConfigMgr Client version is: ' +$installedVersion +': Tagging client for upgrade to version: '+$ClientVersion + $text = 'ConfigMgr Client version is: ' + $installedVersion + ': Tagging client for upgrade to version: ' + $ClientVersion Write-Warning $text $obj = $true } else { - $text = 'ConfigMgr Client version is: ' +$installedVersion +': Required version: '+$ClientVersion +' AutoUpgrade: false. Skipping upgrade' + $text = 'ConfigMgr Client version is: ' + $installedVersion + ': Required version: ' + $ClientVersion + ' AutoUpgrade: false. Skipping upgrade' Write-Output $text $obj = $false } @@ -1237,7 +1238,7 @@ Begin { } Function Test-ClientSiteCode { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $sms = new-object -comobject "Microsoft.SMS.Client" $ClientSiteCode = Get-XMLConfigClientSitecode #[String]$currentSiteCode = Get-Sitecode @@ -1252,7 +1253,7 @@ Begin { #$obj = $false } else { - $text = 'ConfigMgr Client Site Code is "' +$currentSiteCode + '". Expected: "' +$ClientSiteCode +'". Changing sitecode.' + $text = 'ConfigMgr Client Site Code is "' + $currentSiteCode + '". Expected: "' + $ClientSiteCode + '". Changing sitecode.' Write-Warning $text $sms.SetAssignedSite($ClientSiteCode) #$obj = $true @@ -1261,14 +1262,14 @@ Begin { } function Test-PendingReboot { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) # Only run pending reboot check if enabled in config - if (($Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingReboot'} | Select-Object -ExpandProperty 'Enable') -like 'True') { + if (($Xml.Configuration.Option | Where-Object { $_.Name -like 'PendingReboot' } | Select-Object -ExpandProperty 'Enable') -like 'True') { $result = @{ - CBSRebootPending =$false + CBSRebootPending = $false WindowsUpdateRebootRequired = $false - FileRenamePending = $false - SCCMRebootPending = $false + FileRenamePending = $false + SCCMRebootPending = $false } #Check CBS Registry @@ -1281,19 +1282,17 @@ Begin { #Check PendingFileRenameOperations $prop = Get-ItemProperty 'HKLM:SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue - if ($null -ne $prop) - { + if ($null -ne $prop) { #PendingFileRenameOperations is not *must* to reboot? #$result.FileRenamePending = $true } - try - { + try { $util = [wmiclass]'\\.\root\ccm\clientsdk:CCM_ClientUtilities' $status = $util.DetermineIfRebootPending() - if(($null -ne $status) -and $status.RebootPending){ $result.SCCMRebootPending = $true} + if (($null -ne $status) -and $status.RebootPending) { $result.SCCMRebootPending = $true } } - catch{} + catch { } #Return Reboot required if ($result.ContainsValue($true)) { @@ -1317,7 +1316,7 @@ Begin { # Functions to detect and fix errors Function Test-ProvisioningMode { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $registryPath = 'HKLM:\SOFTWARE\Microsoft\CCM\CcmExec' $provisioningMode = (Get-ItemProperty -Path $registryPath).ProvisioningMode @@ -1326,8 +1325,9 @@ Begin { Write-Warning $text Set-ItemProperty -Path $registryPath -Name ProvisioningMode -Value "false" $ArgumentList = @($false) - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -Class 'SMS_Client' -MethodName 'SetClientProvisioningMode' -Arguments @{bEnable=$false} | Out-Null } - else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'SMS_Client' -Name 'SetClientProvisioningMode' -ArgumentList $ArgumentList | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -Class 'SMS_Client' -MethodName 'SetClientProvisioningMode' -Arguments @{bEnable = $false } | Out-Null + } + else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'SMS_Client' -Name 'SetClientProvisioningMode' -ArgumentList $ArgumentList | Out-Null } $log.ProvisioningMode = 'Repaired' } else { @@ -1346,7 +1346,7 @@ Begin { } Function Test-UpdateStore { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) Write-Verbose "Check StateMessage.log if State Messages are successfully forwarded to Management Point" $logdir = Get-CCMLogDirectory $logfile = "$logdir\StateMessage.log" @@ -1366,9 +1366,9 @@ Begin { Function Test-RegistryPol { Param( - [datetime]$StartTime=[datetime]::MinValue, + [datetime]$StartTime = [datetime]::MinValue, $Days, - [Parameter(Mandatory=$true)]$Log) + [Parameter(Mandatory = $true)]$Log) $log.WUAHandler = "Checking" $RepairReason = "" $MachineRegistryFile = "$($env:WinDir)\System32\GroupPolicy\Machine\registry.pol" @@ -1377,8 +1377,8 @@ Begin { Write-Verbose "Check WUAHandler.log for errors since $($StartTime)." $logdir = Get-CCMLogDirectory $logfile = "$logdir\WUAHandler.log" - $logLine = Search-CMLogFile -LogFile $logfile -StartTime $StartTime -SearchStrings @('0x80004005','0x87d00692') - if ($logLine) {$RepairReason = "WUAHandler Log"} + $logLine = Search-CMLogFile -LogFile $logfile -StartTime $StartTime -SearchStrings @('0x80004005', '0x87d00692') + if ($logLine) { $RepairReason = "WUAHandler Log" } # Check 2 - Registry.pol is too old. if ($Days) { @@ -1387,7 +1387,7 @@ Begin { $file = Get-ChildItem -Path $MachineRegistryFile -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty LastWriteTime $regPolDate = Get-Date($file) $now = Get-Date - if (($now - $regPolDate).Days -ge $Days) {$RepairReason = "File Age"} + if (($now - $regPolDate).Days -ge $Days) { $RepairReason = "File Age" } } catch { Write-Warning "GPO Cache: Failed to check machine policy age." } } @@ -1396,21 +1396,21 @@ Begin { #Event IDs documented here: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc749336(v=ws.10)#troubleshooting-group-policy-using-event-logs-1 try { Write-Verbose "Checking the Group Policy event log for errors since $($StartTime)." - $numberOfGPOErrors = (Get-WinEvent -Verbose:$false -FilterHashTable @{LogName='Microsoft-Windows-GroupPolicy/Operational';Level=2;StartTime=$StartTime} -ErrorAction SilentlyContinue | Where-Object {($_.ID -ge 7000 -and $_.ID -le 7007) -or ($_.ID -ge 7017 -and $_.ID -le 7299) -or ($_.ID -eq 1096)}).Count - if ($numberOfGPOErrors -gt 0) {$RepairReason = "Event Log"} + $numberOfGPOErrors = (Get-WinEvent -Verbose:$false -FilterHashTable @{LogName = 'Microsoft-Windows-GroupPolicy/Operational'; Level = 2; StartTime = $StartTime } -ErrorAction SilentlyContinue | Where-Object { ($_.ID -ge 7000 -and $_.ID -le 7007) -or ($_.ID -ge 7017 -and $_.ID -le 7299) -or ($_.ID -eq 1096) }).Count + if ($numberOfGPOErrors -gt 0) { $RepairReason = "Event Log" } } catch { Write-Warning "GPO Cache: Failed to check the event log for policy errors." } #If we need to repart the policy files then do so. - if ($RepairReason -ne ""){ + if ($RepairReason -ne "") { $log.WUAHandler = "Broken ($RepairReason)" Write-Output "GPO Cache: Broken ($RepairReason)" Write-Verbose 'Deleting registry.pol and running gpupdate...' - try { if (Test-Path -Path $MachineRegistryFile) {Remove-Item $MachineRegistryFile -Force } } + try { if (Test-Path -Path $MachineRegistryFile) { Remove-Item $MachineRegistryFile -Force } } catch { Write-Warning "GPO Cache: Failed to remove the registry file ($($MachineRegistryFile))." } - finally { & Write-Output n | gpupdate.exe /force /target:computer | Out-Null } + finally { & Write-Output n | gpupdate.exe /force /target:computer | Out-Null } #Write-Verbose 'Sleeping for 1 minute to allow for group policy to refresh' #Start-Sleep -Seconds 60 @@ -1429,7 +1429,7 @@ Begin { } Function Test-ClientLogSize { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) try { [int]$currentLogSize = Get-ClientMaxLogSize } catch { [int]$currentLogSize = 0 } try { [int]$currentMaxHistory = Get-ClientMaxLogHistory } @@ -1453,7 +1453,7 @@ Begin { } else { if ($currentLogSize -ne $clientLogSize) { - $text = 'ConfigMgr Client Max Log Size: Configuring to '+ $clientLogSize +' KB' + $text = 'ConfigMgr Client Max Log Size: Configuring to ' + $clientLogSize + ' KB' $Log.MaxLogSize = $clientLogSize Write-Warning $text } @@ -1462,7 +1462,7 @@ Begin { Write-Host $text } if ($currentMaxHistory -ne $clientLogMaxHistory) { - $text = 'ConfigMgr Client Max Log History: Configuring to ' +$clientLogMaxHistory + $text = 'ConfigMgr Client Max Log History: Configuring to ' + $clientLogMaxHistory $Log.MaxLogHistory = $clientLogMaxHistory Write-Warning $text } @@ -1474,7 +1474,8 @@ Begin { $newLogSize = [int]$clientLogSize $newLogSize = $newLogSize * 1000 - if ($PowerShellVersion -ge 6) {Invoke-CimMethod -Namespace "root/ccm" -ClassName "sms_client" -MethodName SetGlobalLoggingConfiguration -Arguments @{LogLevel=$loglevel; LogMaxHistory=$clientLogMaxHistory; LogMaxSize=$newLogSize} } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace "root/ccm" -ClassName "sms_client" -MethodName SetGlobalLoggingConfiguration -Arguments @{LogLevel = $loglevel; LogMaxHistory = $clientLogMaxHistory; LogMaxSize = $newLogSize } + } else { $smsClient = [wmiclass]"root/ccm:sms_client" $smsClient.SetGlobalLoggingConfiguration($logLevel, $newLogSize, $clientLogMaxHistory) @@ -1499,7 +1500,7 @@ Begin { $CCMCache = "$env:SystemDrive\Windows\ccmcache" $CCMCache = (New-Object -ComObject "UIResource.UIResourceMgr").GetCacheInfo().Location if ($null -eq $CCMCache) { $CCMCache = "$env:SystemDrive\Windows\ccmcache" } - $ValidCachedFolders = (New-Object -ComObject "UIResource.UIResourceMgr").GetCacheInfo().GetCacheElements() | ForEach-Object {$_.Location} + $ValidCachedFolders = (New-Object -ComObject "UIResource.UIResourceMgr").GetCacheInfo().GetCacheElements() | ForEach-Object { $_.Location } $AllCachedFolders = (Get-ChildItem -Path $CCMCache) | Select-Object Fullname -ExpandProperty Fullname ForEach ($CachedFolder in $AllCachedFolders) { @@ -1513,14 +1514,14 @@ Begin { } } catch { Write-Host "Failed Clearing ConfigMgr orphaned Cache items." } - } + } Function Resolve-Client { Param( - [Parameter(Mandatory=$false)]$Xml, - [Parameter(Mandatory=$true)]$ClientInstallProperties, - [Parameter(Mandatory=$false)]$FirstInstall=$false - ) + [Parameter(Mandatory = $false)]$Xml, + [Parameter(Mandatory = $true)]$ClientInstallProperties, + [Parameter(Mandatory = $false)]$FirstInstall = $false + ) $ClientShare = Get-XMLConfigClientShare if ((Test-Path $ClientShare -ErrorAction SilentlyContinue) -eq $true) { @@ -1534,22 +1535,22 @@ Begin { Write-Verbose "Enforce registration of common DLL files to make sure CCM Agent works." $DllFiles = 'actxprxy.dll', 'atl.dll', 'Bitsprx2.dll', 'Bitsprx3.dll', 'browseui.dll', 'cryptdlg.dll', 'dssenh.dll', 'gpkcsp.dll', 'initpki.dll', 'jscript.dll', 'mshtml.dll', 'msi.dll', 'mssip32.dll', 'msxml.dll', 'msxml3.dll', 'msxml3a.dll', 'msxml3r.dll', 'msxml4.dll', 'msxml4a.dll', 'msxml4r.dll', 'msxml6.dll', 'msxml6r.dll', 'muweb.dll', 'ole32.dll', 'oleaut32.dll', 'Qmgr.dll', 'Qmgrprxy.dll', 'rsaenh.dll', 'sccbase.dll', 'scrrun.dll', 'shdocvw.dll', 'shell32.dll', 'slbcsp.dll', 'softpub.dll', 'rlmon.dll', 'userenv.dll', 'vbscript.dll', 'Winhttp.dll', 'wintrust.dll', 'wuapi.dll', 'wuaueng.dll', 'wuaueng1.dll', 'wucltui.dll', 'wucltux.dll', 'wups.dll', 'wups2.dll', 'wuweb.dll', 'wuwebv.dll', 'Xpob2res.dll', 'WBEM\wmisvc.dll' foreach ($Dll in $DllFiles) { - $file = $env:windir +"\System32\$Dll" + $file = $env:windir + "\System32\$Dll" Register-DLLFile -FilePath $File } if ($Uninstall -eq $true) { - Write-Verbose "Trigger ConfigMgr Client uninstallation using Invoke-Expression." - Invoke-Expression "&'$ClientShare\ccmsetup.exe' /uninstall" - - $launched = $true - do { - Start-Sleep -seconds 5 - if (Get-Process "ccmsetup" -ErrorAction SilentlyContinue) { - Write-Verbose "ConfigMgr Client Uninstallation still running" - $launched = $true - } - else { $launched = $false } + Write-Verbose "Trigger ConfigMgr Client uninstallation using Invoke-Expression." + Invoke-Expression "&'$ClientShare\ccmsetup.exe' /uninstall" + + $launched = $true + do { + Start-Sleep -seconds 5 + if (Get-Process "ccmsetup" -ErrorAction SilentlyContinue) { + Write-Verbose "ConfigMgr Client Uninstallation still running" + $launched = $true + } + else { $launched = $false } } while ($launched -eq $true) } @@ -1557,14 +1558,14 @@ Begin { Write-Verbose "Client install string: $ClientShare\ccmsetup.exe $ClientInstallProperties" Invoke-Expression "&'$ClientShare\ccmsetup.exe' $ClientInstallProperties" - $launched = $true - do { - Start-Sleep -seconds 5 - if (Get-Process "ccmsetup" -ErrorAction SilentlyContinue) { - Write-Verbose "ConfigMgr Client installation still running" - $launched = $true - } - else { $launched = $false } + $launched = $true + do { + Start-Sleep -seconds 5 + if (Get-Process "ccmsetup" -ErrorAction SilentlyContinue) { + Write-Verbose "ConfigMgr Client installation still running" + $launched = $true + } + else { $launched = $false } } while ($launched -eq $true) if ($FirstInstall -eq $true) { @@ -1576,7 +1577,7 @@ Begin { } else { - $text = 'ERROR: Client tagged for reinstall, but failed to access fileshare: ' +$ClientShare + $text = 'ERROR: Client tagged for reinstall, but failed to access fileshare: ' + $ClientShare Write-Error $text Exit 1 } @@ -1587,18 +1588,18 @@ Begin { param ([string]$FilePath) try { $Result = Start-Process -FilePath 'regsvr32.exe' -Args "/s `"$FilePath`"" -Wait -NoNewWindow -PassThru } - catch {} + catch { } } Function Test-WMI { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $vote = 0 $result = winmgmt /verifyrepository switch -wildcard ($result) { # Always fix if this returns inconsistent "*inconsistent*" { $vote = 100 } # English - "*not consistent*" { $vote = 100 } # English + "*not consistent*" { $vote = 100 } # English "*inkonsekvent*" { $vote = 100 } # Swedish "*epäyhtenäinen*" { $vote = 100 } # Finnish "*inkonsistent*" { $vote = 100 } # German @@ -1608,7 +1609,8 @@ Begin { Try { if ($PowerShellVersion -ge 6) { $WMI = Get-CimInstance Win32_ComputerSystem -ErrorAction Stop } else { $WMI = Get-WmiObject Win32_ComputerSystem -ErrorAction Stop } - } Catch { + } + Catch { Write-Verbose 'Failed to connect to WMI class "Win32_ComputerSystem". Voting for WMI fix...' $vote++ } @@ -1616,10 +1618,12 @@ Begin { Try { if ($PowerShellVersion -ge 6) { $WMI = Get-CimInstance -Namespace root/ccm -Class SMS_Client -ErrorAction Stop } else { $WMI = Get-WmiObject -Namespace root/ccm -Class SMS_Client -ErrorAction Stop } - } Catch { + } + Catch { Write-Verbose 'Failed to connect to WMI namespace "root/ccm" class "SMS_Client". Tagging client for reinstall instead of WMI fix.' $obj = $true - } Finally { + } + Finally { if ($vote -eq 0) { $text = 'WMI Check: OK' $log.WMI = 'OK' @@ -1648,11 +1652,11 @@ Begin { } Function Repair-WMI { - $text ='Repairing WMI' + $text = 'Repairing WMI' Write-Output $text # Check PATH - if((! (@(($ENV:PATH).Split(";")) -contains "$env:SystemDrive\WINDOWS\System32\Wbem")) -and (! (@(($ENV:PATH).Split(";")) -contains "%systemroot%\System32\Wbem"))){ + if ((! (@(($ENV:PATH).Split(";")) -contains "$env:SystemDrive\WINDOWS\System32\Wbem")) -and (! (@(($ENV:PATH).Split(";")) -contains "%systemroot%\System32\Wbem"))) { $text = "WMI Folder not in search path!." Write-Warning $text } @@ -1661,18 +1665,18 @@ Begin { Stop-Service -Force winmgmt # WMI Binaries - [String[]]$aWMIBinaries=@("unsecapp.exe","wmiadap.exe","wmiapsrv.exe","wmiprvse.exe","scrcons.exe") - foreach ($sWMIPath in @(($ENV:SystemRoot+"\System32\wbem"),($ENV:SystemRoot+"\SysWOW64\wbem"))) { - if(Test-Path -Path $sWMIPath){ + [String[]]$aWMIBinaries = @("unsecapp.exe", "wmiadap.exe", "wmiapsrv.exe", "wmiprvse.exe", "scrcons.exe") + foreach ($sWMIPath in @(($ENV:SystemRoot + "\System32\wbem"), ($ENV:SystemRoot + "\SysWOW64\wbem"))) { + if (Test-Path -Path $sWMIPath) { push-Location $sWMIPath - foreach($sBin in $aWMIBinaries){ - if(Test-Path -Path $sBin){ - $oCurrentBin=Get-Item -Path $sBin + foreach ($sBin in $aWMIBinaries) { + if (Test-Path -Path $sBin) { + $oCurrentBin = Get-Item -Path $sBin & $oCurrentBin.FullName /RegServer } - else{ + else { # Warning only for System32 - if($sWMIPath -eq $ENV:SystemRoot+"\System32\wbem"){ + if ($sWMIPath -eq $ENV:SystemRoot + "\System32\wbem") { Write-Warning "File $sBin not found!" } } @@ -1683,8 +1687,8 @@ Begin { # Reregister Managed Objects Write-Verbose "Reseting Repository..." - & ($ENV:SystemRoot+"\system32\wbem\winmgmt.exe") /resetrepository - & ($ENV:SystemRoot+"\system32\wbem\winmgmt.exe") /salvagerepository + & ($ENV:SystemRoot + "\system32\wbem\winmgmt.exe") /resetrepository + & ($ENV:SystemRoot + "\system32\wbem\winmgmt.exe") /salvagerepository Start-Service winmgmt $text = 'Tagging ConfigMgr client for reinstall' Write-Warning $text @@ -1693,11 +1697,11 @@ Begin { # Test if the compliance state messages should be resent. Function Test-RefreshComplianceState { Param( - $Days=0, - [Parameter(Mandatory=$true)]$RegistryKey, - [Parameter(Mandatory=$true)]$Log + $Days = 0, + [Parameter(Mandatory = $true)]$RegistryKey, + [Parameter(Mandatory = $true)]$Log ) - $RegValueName="RefreshServerComplianceState" + $RegValueName = "RefreshServerComplianceState" #Get the last time this script was ran. If the registry isn't found just use the current date. Try { [datetime]$LastSent = Get-RegistryValue -Path $RegistryKey -Name $RegValueName } @@ -1708,19 +1712,19 @@ Begin { $NumberOfDays = (New-Timespan -Start (Get-Date) -End ($LastSent.AddDays($Days))).Days #Resend complianc states if the next interval has already arrived or randomly based on the number of days left until the next interval. - If (($NumberOfDays -le 0) -or ((Get-Random -Maximum $NumberOfDays) -eq 0 )){ - Try{ + If (($NumberOfDays -le 0) -or ((Get-Random -Maximum $NumberOfDays) -eq 0 )) { + Try { Write-Verbose "Resending compliance states." (New-Object -ComObject Microsoft.CCM.UpdatesStore).RefreshServerComplianceState() - $LastSent=Get-Date + $LastSent = Get-Date Write-Output "Compliance States: Refreshed." } - Catch{ + Catch { Write-Error "Failed to resend the compliance states." - $LastSent=[datetime]::MinValue + $LastSent = [datetime]::MinValue } } - Else{ + Else { Write-Output "Compliance States: OK." } @@ -1733,8 +1737,8 @@ Begin { # Start ConfigMgr Agent if not already running Function Test-SCCMService { if ($service.Status -ne 'Running') { - try {Start-Service -Name CcmExec | Out-Null} - catch {} + try { Start-Service -Name CcmExec | Out-Null } + catch { } } } @@ -1750,22 +1754,20 @@ Begin { write-host "SMSTSMgr: Adding dependency on Windows Management Instrumentaion service." start-process sc.exe -ArgumentList "config smstsmgr depend= winmgmt" -wait } - else { Write-Host "SMSTSMgr: OK"} + else { Write-Host "SMSTSMgr: OK" } } # Windows Service Functions Function Test-Services { - Param([Parameter(Mandatory=$false)]$Xml, $log, $Webservice, $ProfileID) + Param([Parameter(Mandatory = $false)]$Xml, $log, $Webservice, $ProfileID) $log.Services = 'OK' # Test services defined by config.xml - if ($Config) - { + if ($Config) { Write-Verbose 'Test services from XML configuration file' - foreach ($service in $Xml.Configuration.Service) - { + foreach ($service in $Xml.Configuration.Service) { $startuptype = ($service.StartupType).ToLower() if ($startuptype -like "automatic (delayed start)") { $service.StartupType = "automaticd" } @@ -1781,23 +1783,22 @@ Begin { } # Test services defined by console extension using webservice - if ($Webservice) - { + if ($Webservice) { $Services = Get-ConfigServicesFromWebservice -URI $Webservice -ProfileID $ProfileID # define startup type foreach ($service in $Services) { $start = $service.StartupType switch ($start) { - 0 { $StartupType = "disabled"} - 1 { $StartupType = "manual"} - 2 { $StartupType = "automatic"} - 3 { $StartupType = "automaticd"} + 0 { $StartupType = "disabled" } + 1 { $StartupType = "manual" } + 2 { $StartupType = "automatic" } + 3 { $StartupType = "automaticd" } } $stat = $service.state switch ($stat) { - "False" { $state = "stopped"} - "True" { $state = "running"} + "False" { $state = "stopped" } + "True" { $state = "running" } } $uptime = $service.uptime @@ -1813,19 +1814,19 @@ Begin { Function Test-Service { param( - [Parameter(Mandatory=$True, - HelpMessage='Name')] - [string]$Name, - [Parameter(Mandatory=$True, - HelpMessage='StartupType: Automatic, Automatic (Delayed Start), Manual, Disabled')] - [string]$StartupType, - [Parameter(Mandatory=$True, - HelpMessage='State: Running, Stopped')] - [string]$State, - [Parameter(Mandatory=$False, - HelpMessage='Updatime in days')] - [int]$Uptime, - [Parameter(Mandatory=$True)]$log + [Parameter(Mandatory = $True, + HelpMessage = 'Name')] + [string]$Name, + [Parameter(Mandatory = $True, + HelpMessage = 'StartupType: Automatic, Automatic (Delayed Start), Manual, Disabled')] + [string]$StartupType, + [Parameter(Mandatory = $True, + HelpMessage = 'State: Running, Stopped')] + [string]$State, + [Parameter(Mandatory = $False, + HelpMessage = 'Updatime in days')] + [int]$Uptime, + [Parameter(Mandatory = $True)]$log ) $OSName = Get-OperatingSystem @@ -1833,10 +1834,10 @@ Begin { # Handle all sorts of casing and mispelling of delayed and triggerd start in config.xml services $val = $StartupType.ToLower() switch -Wildcard ($val) { - "automaticd*" {$StartupType = "Automatic (Delayed Start)"} - "automatic(d*" {$StartupType = "Automatic (Delayed Start)"} - "automatic(t*" {$StartupType = "Automatic (Trigger Start)"} - "automatict*" {$StartupType = "Automatic (Trigger Start)"} + "automaticd*" { $StartupType = "Automatic (Delayed Start)" } + "automatic(d*" { $StartupType = "Automatic (Delayed Start)" } + "automatic(t*" { $StartupType = "Automatic (Trigger Start)" } + "automatict*" { $StartupType = "Automatic (Trigger Start)" } } $path = "HKLM:\SYSTEM\CurrentControlSet\Services\$name" @@ -1863,13 +1864,12 @@ Begin { "automatic (t*" {$serviceStartType = "Automatic (Trigger Start)"} "automatic t*" {$serviceStartType = "Automatic (Trigger Start)"} #> - "manual" {$serviceStartType = "Manual"} - "disabled" {$serviceStartType = "Disabled"} + "manual" { $serviceStartType = "Manual" } + "disabled" { $serviceStartType = "Disabled" } } Write-Verbose "Verify startup type" - if ($serviceStartType -eq $StartupType) - { + if ($serviceStartType -eq $StartupType) { $text = "Service $Name startup: OK" Write-Output $text } @@ -1907,26 +1907,26 @@ Begin { Write-Verbose 'Verify service is running' if ($service.Status -eq "Running") { - $text = 'Service ' +$Name+' running: OK' + $text = 'Service ' + $Name + ' running: OK' Write-Output $text #If we are checking uptime. - If ($Uptime){ + If ($Uptime) { Write-Verbose "Verify the $($Name) service hasn't exceeded uptime of $($Uptime) days." - $ServiceUptime= Get-ServiceUpTime -Name $Name + $ServiceUptime = Get-ServiceUpTime -Name $Name if ($ServiceUptime -ge $Uptime) { try { #Before restarting the service wait for some known processes to end. Restarting the service while an app or updates is installing might cause issues. $Timer = [Diagnostics.Stopwatch]::StartNew() $WaitMinutes = 30 - $ProcessesStopped=$True - While ((Get-Process -Name WUSA,wuauclt,setup,TrustedInstaller,msiexec,TiWorker,ccmsetup -ErrorAction SilentlyContinue).Count -gt 0){ + $ProcessesStopped = $True + While ((Get-Process -Name WUSA, wuauclt, setup, TrustedInstaller, msiexec, TiWorker, ccmsetup -ErrorAction SilentlyContinue).Count -gt 0) { $MinutesLeft = $WaitMinutes - $Timer.Elapsed.Minutes - If($MinutesLeft -le 0){ + If ($MinutesLeft -le 0) { Write-Warning "Timed out waiting $($WaitMinutes) minutes for installation processes to complete. Will not restart the $($Name) service." - $ProcessesStopped=$False + $ProcessesStopped = $False Break } Write-Warning "Waiting $($MinutesLeft) minutes for installation processes to complete." @@ -1935,13 +1935,14 @@ Begin { $Timer.Stop() #If the processes are not running the restart the service. - If ($ProcessesStopped){ + If ($ProcessesStopped) { Write-Output "Restarting service: $($Name)..." Restart-Service -Name $service.Name -Force Write-Output "Restarted service: $($Name)..." $log.Services = 'Restarted' } - } catch { + } + catch { $text = "Failed to restart service $($Name)" Write-Error $text } @@ -1959,37 +1960,39 @@ Begin { Stop-Process -ID $ServicePID -Force:$true -Confirm:$false -ErrorAction Stop Write-Verbose "Succesfully stopped the $Name service process which was in a degraded state." } - Catch{ + Catch { Write-Error "Failed to force $Name process to stop." } } try { - $RetryService= $False + $RetryService = $False $text = 'Starting service: ' + $Name + '...' Write-Output $text Start-Service -Name $service.Name -ErrorAction Stop $log.Services = 'Started' - } catch { + } + catch { #Error 1290 (-2146233087) indicates that the service is sharing a thread with another service that is protected and cannot share its thread. #This is resolved by configuring the service to run on its own thread. - If ($_.Exception.Hresult -eq '-2146233087'){ + If ($_.Exception.Hresult -eq '-2146233087') { Write-Output "Failed to start service $Name because it's sharing a thread with another process. Changing to use its own thread." & cmd /c sc config $Name type= own - $RetryService= $True + $RetryService = $True } - Else{ - $text = 'Failed to start service ' +$Name + Else { + $text = 'Failed to start service ' + $Name Write-Error $text } } #If a recoverable error was found, try starting it again. - If ($RetryService){ + If ($RetryService) { try { Start-Service -Name $service.Name -ErrorAction Stop $log.Services = 'Started' - } catch { - $text = 'Failed to start service ' +$Name + } + catch { + $text = 'Failed to start service ' + $Name Write-Error $text } } @@ -1997,10 +2000,10 @@ Begin { } function Test-AdminShare { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) Write-Verbose "Test the ADMIN$ and C$" - if ($PowerShellVersion -ge 6) { $share = Get-CimInstance Win32_Share | Where-Object {$_.Name -like 'ADMIN$'} } - else { $share = Get-WmiObject Win32_Share | Where-Object {$_.Name -like 'ADMIN$'} } + if ($PowerShellVersion -ge 6) { $share = Get-CimInstance Win32_Share | Where-Object { $_.Name -like 'ADMIN$' } } + else { $share = Get-WmiObject Win32_Share | Where-Object { $_.Name -like 'ADMIN$' } } #$shareClass = [WMICLASS]"WIN32_Share" # Depreciated if ($share.Name -contains 'ADMIN$') { @@ -2009,8 +2012,8 @@ Begin { } else { $fix = $true } - if ($PowerShellVersion -ge 6) { $share = Get-CimInstance Win32_Share | Where-Object {$_.Name -like 'C$'} } - else { $share = Get-WmiObject Win32_Share | Where-Object {$_.Name -like 'C$'} } + if ($PowerShellVersion -ge 6) { $share = Get-CimInstance Win32_Share | Where-Object { $_.Name -like 'C$' } } + else { $share = Get-WmiObject Win32_Share | Where-Object { $_.Name -like 'C$' } } #$shareClass = [WMICLASS]'WIN32_Share' # Depreciated if ($share.Name -contains "C$") { @@ -2031,16 +2034,40 @@ Begin { Function Test-DiskSpace { $XMLDiskSpace = Get-XMLConfigOSDiskFreeSpace - if ($PowerShellVersion -ge 6) { $driveC = Get-CimInstance -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object FreeSpace, Size } - else { $driveC = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "$env:SystemDrive"} | Select-Object FreeSpace, Size } + if ($PowerShellVersion -ge 6) { $driveC = Get-CimInstance -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object FreeSpace, Size } + else { $driveC = Get-WmiObject -Class Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "$env:SystemDrive" } | Select-Object FreeSpace, Size } $freeSpace = (($driveC.FreeSpace / $driveC.Size) * 100) - + $fix = (Get-XMLConfigOSDiskFreeSpaceFix).ToLower() if ($freeSpace -le $XMLDiskSpace) { - $text = "Local disk $env:SystemDrive Less than $XMLDiskSpace % free space" - Write-Error $text + if ($fix -eq "True") { + #Ref: https://support.microsoft.com/en-us/help/253597/automating-disk-cleanup-tool-in-windows + $SageSetFlag = "201906" + $VolumeCacheTargets = @("Old ChkDsk Files", "Previous Installations", "Service Pack Cleanup", "Update Cleanup") + foreach ($VolumeCache in $VolumeCacheTargets) { + if ((Test-Path -LiteralPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache") -eq $true) { + New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache" -Name "StateFlags$SageSetFlag" -Value 2 -PropertyType DWord -Force -ea SilentlyContinue; + } + } + #Write-host "Starting CleanMgr" + Start-Process -FilePath CleanMgr.exe -ArgumentList "/sagerun:$SageSetFlag" -WindowStyle Hidden + #remove flags + foreach ($VolumeCache in $VolumeCacheTargets) { + if ((Test-Path -LiteralPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache") -eq $true) { + Remove-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\$VolumeCache" -Name "StateFlags$SageSetFlag" -ea SilentlyContinue; + } + } + $text = "Local disk $env:SystemDrive less then $XMLDiskSpace % free space, Cleanup Invoked." + $log.OSDiskCleanup = $text + } + else { + $text = "Local disk $env:SystemDrive Less than $XMLDiskSpace % free space, and Cleanup not enabled" + $log.OSDiskCleanup = $text + Write-Error $text + } } else { - $text ="Free space $env:SystemDrive OK" + $text = "Free space $env:SystemDrive OK" + $log.OSDiskCleanup = $text Write-Output $text } } @@ -2057,11 +2084,11 @@ Begin { } Function Get-LastReboot { - Param([Parameter(Mandatory=$false)][xml]$Xml) + Param([Parameter(Mandatory = $false)][xml]$Xml) # Only run if option in config is enabled if ($config) { - if (($Xml.Configuration.Option | Where-Object {$_.Name -like 'RebootApplication'} | Select-Object -ExpandProperty 'Enable') -like 'True') { $execute = $true } + if (($Xml.Configuration.Option | Where-Object { $_.Name -like 'RebootApplication' } | Select-Object -ExpandProperty 'Enable') -like 'True') { $execute = $true } } if ($Webservice) { $execute = $true @@ -2077,16 +2104,16 @@ Begin { $uptime = (Get-Date) - ($wmi.ConvertToDateTime($wmi.lastbootuptime)) if ($uptime.TotalDays -lt $maxRebootDays) { - $text = 'Last boot time: ' +$lastBootTime + ': OK' + $text = 'Last boot time: ' + $lastBootTime + ': OK' Write-Output $text } elseif (($uptime.TotalDays -ge $maxRebootDays) -and (Get-XMLConfigRebootApplicationEnable -eq $true)) { - $text = 'Last boot time: ' +$lastBootTime + ': More than '+$maxRebootDays +' days since last reboot. Starting reboot application.' + $text = 'Last boot time: ' + $lastBootTime + ': More than ' + $maxRebootDays + ' days since last reboot. Starting reboot application.' Write-Warning $text Start-RebootApplication } else { - $text = 'Last boot time: ' +$lastBootTime + ': More than '+$maxRebootDays +' days since last reboot. Reboot application disabled.' + $text = 'Last boot time: ' + $lastBootTime + ': More than ' + $maxRebootDays + ' days since last reboot. Reboot application disabled.' Write-Warning $text } } @@ -2096,33 +2123,33 @@ Begin { $taskName = 'ConfigMgr Client Health - Reboot on demand' #$OS = Get-OperatingSystem #if ($OS -like "*Windows 7*") { - $task = schtasks.exe /query | FIND /I "ConfigMgr Client Health - Reboot" + $task = schtasks.exe /query | FIND /I "ConfigMgr Client Health - Reboot" #} #else { $task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue } if ($task -eq $null) { New-RebootTask -taskName $taskName } #if ($OS -notlike "*Windows 7*") {Start-ScheduledTask -TaskName $taskName } #else { - schtasks.exe /Run /TN $taskName + schtasks.exe /Run /TN $taskName #} } Function New-RebootTask { - Param([Parameter(Mandatory=$true)]$taskName) + Param([Parameter(Mandatory = $true)]$taskName) $rebootApp = Get-XMLConfigRebootApplication # $execute is the executable file, $arguement is all the arguments added to it. - $execute,$arguments = $rebootApp.Split(' ') + $execute, $arguments = $rebootApp.Split(' ') $argument = $null foreach ($i in $arguments) { $argument += $i + " " } # Trim the " " from argument if present - $i = $argument.Length -1 - if ($argument.Substring($i) -eq ' ') { $argument = $argument.Substring(0, $argument.Length -1) } + $i = $argument.Length - 1 + if ($argument.Substring($i) -eq ' ') { $argument = $argument.Substring(0, $argument.Length - 1) } #$OS = Get-OperatingSystem #if ($OS -like "*Windows 7*") { - schtasks.exe /Create /tn $taskName /tr "$execute $argument" /ru "BUILTIN\Users" /sc ONCE /st 00:00 /sd 01/01/1901 + schtasks.exe /Create /tn $taskName /tr "$execute $argument" /ru "BUILTIN\Users" /sc ONCE /st 00:00 /sd 01/01/1901 #} <# else { @@ -2140,12 +2167,12 @@ Begin { } Function Test-MissingDrivers { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) $FileLogLevel = ((Get-XMLConfigLoggingLevel).ToString()).ToLower() $i = 0 - if ($PowerShellVersion -ge 6) { $devices = Get-CimInstance Win32_PNPEntity | Where-Object{ ($_.ConfigManagerErrorCode -ne 0) -and ($_.ConfigManagerErrorCode -ne 22) -and ($_.Name -notlike "*PS/2*") } | Select-Object Name, DeviceID } - else { $devices = Get-WmiObject Win32_PNPEntity | Where-Object{ ($_.ConfigManagerErrorCode -ne 0) -and ($_.ConfigManagerErrorCode -ne 22) -and ($_.Name -notlike "*PS/2*") } | Select-Object Name, DeviceID } - $devices | ForEach-Object {$i++} + if ($PowerShellVersion -ge 6) { $devices = Get-CimInstance Win32_PNPEntity | Where-Object { ($_.ConfigManagerErrorCode -ne 0) -and ($_.ConfigManagerErrorCode -ne 22) -and ($_.Name -notlike "*PS/2*") } | Select-Object Name, DeviceID } + else { $devices = Get-WmiObject Win32_PNPEntity | Where-Object { ($_.ConfigManagerErrorCode -ne 0) -and ($_.ConfigManagerErrorCode -ne 22) -and ($_.Name -notlike "*PS/2*") } | Select-Object Name, DeviceID } + $devices | ForEach-Object { $i++ } if ($devices -ne $null) { $text = "Drivers: $i unknown or faulty device(s)" @@ -2153,7 +2180,7 @@ Begin { $log.Drivers = "$i unknown or faulty driver(s)" foreach ($device in $devices) { - $text = 'Missing or faulty driver: ' +$device.Name + '. Device ID: ' + $device.DeviceID + $text = 'Missing or faulty driver: ' + $device.Name + '. Device ID: ' + $device.DeviceID Write-Warning $text if (-NOT($FileLogLevel -like "clientlocal")) { Out-LogFile -Xml $xml -Text $text } } @@ -2168,9 +2195,9 @@ Begin { # Function to store SCCM log file changes to be processed Function New-SCCMLogFileJob { Param( - [Parameter(Mandatory=$true)]$Logfile, - [Parameter(Mandatory=$true)]$Text, - [Parameter(Mandatory=$true)]$SCCMLogJobs + [Parameter(Mandatory = $true)]$Logfile, + [Parameter(Mandatory = $true)]$Text, + [Parameter(Mandatory = $true)]$SCCMLogJobs ) $path = Get-CCMLogDirectory @@ -2180,19 +2207,21 @@ Begin { # Function to remove info in SCCM logfiles after remediation. This to prevent false positives triggering remediation next time script runs Function Update-SCCMLogFile { - Param([Parameter(Mandatory=$true)]$SCCMLogJobs) + Param([Parameter(Mandatory = $true)]$SCCMLogJobs) Write-Verbose "Start Update-SCCMLogFile" - foreach ($job in $SCCMLogJobs) { get-content -Path $job.File | Where-Object {$_ -notmatch $job.Text} | Out-File $job.File -Force } + foreach ($job in $SCCMLogJobs) { get-content -Path $job.File | Where-Object { $_ -notmatch $job.Text } | Out-File $job.File -Force } Write-Verbose "End Update-SCCMLogFile" } Function Test-SCCMHardwareInventoryScan { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) Write-Verbose "Start Test-SCCMHardwareInventoryScan" $days = Get-XMLConfigHardwareInventoryDays - if ($PowerShellVersion -ge 6) { $wmi = Get-CimInstance -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object {$_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}'} | Select-Object @{label='HWSCAN';expression={$_.ConvertToDateTime($_.LastCycleStartedDate)}} } - else { $wmi = Get-WmiObject -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object {$_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}'} | Select-Object @{label='HWSCAN';expression={$_.ConvertToDateTime($_.LastCycleStartedDate)}} } + if ($PowerShellVersion -ge 6) { $wmi = Get-CimInstance -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object { $_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}' } | Select-Object @{label = 'HWSCAN'; expression = { $_.ConvertToDateTime($_.LastCycleStartedDate) } } + } + else { $wmi = Get-WmiObject -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object { $_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}' } | Select-Object @{label = 'HWSCAN'; expression = { $_.ConvertToDateTime($_.LastCycleStartedDate) } } + } $HWScanDate = $wmi | Select-Object -ExpandProperty HWSCAN $HWScanDate = Get-SmallDateTime $HWScanDate $minDate = Get-SmallDateTime((Get-Date).AddDays(-$days)) @@ -2204,8 +2233,10 @@ Begin { Get-SCCMPolicyHardwareInventory # Get the new date after policy trigger - if ($PowerShellVersion -ge 6) { $wmi = Get-CimInstance -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object {$_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}'} | Select-Object @{label='HWSCAN';expression={$_.ConvertToDateTime($_.LastCycleStartedDate)}} } - else { $wmi = Get-WmiObject -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object {$_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}'} | Select-Object @{label='HWSCAN';expression={$_.ConvertToDateTime($_.LastCycleStartedDate)}} } + if ($PowerShellVersion -ge 6) { $wmi = Get-CimInstance -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object { $_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}' } | Select-Object @{label = 'HWSCAN'; expression = { $_.ConvertToDateTime($_.LastCycleStartedDate) } } + } + else { $wmi = Get-WmiObject -Namespace root\ccm\invagt -Class InventoryActionStatus | Where-Object { $_.InventoryActionID -eq '{00000000-0000-0000-0000-000000000001}' } | Select-Object @{label = 'HWSCAN'; expression = { $_.ConvertToDateTime($_.LastCycleStartedDate) } } + } $HWScanDate = $wmi | Select-Object -ExpandProperty HWSCAN $HWScanDate = Get-SmallDateTime -Date $HWScanDate } @@ -2226,7 +2257,7 @@ Begin { # TODO: Implement so result of this remediation is stored in WMI log object, next to result of previous WMI check. This do not require db or webservice update # ref: https://social.technet.microsoft.com/Forums/de-DE/1f48e8d8-4e13-47b5-ae1b-dcb831c0a93b/setup-was-unable-to-compile-the-file-discoverystatusmof-the-error-code-is-8004100e?forum=configmanagerdeployment Function Test-PolicyPlatform { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) try { if (Get-WmiObject -Namespace 'root/Microsoft' -Class '__Namespace' -Filter 'Name = "PolicyPlatform"') { Write-Host "PolicyPlatform: OK" } else { @@ -2255,12 +2286,12 @@ Begin { if ($PowerShellVersion -ge 6) { $obj = (Get-CimInstance Win32_NTDomain).ClientSiteName } else { $obj = (Get-WmiObject Win32_NTDomain).ClientSiteName } } - catch {$obj = $false} + catch { $obj = $false } finally { if ($obj -ne $false) { Write-Output ($obj | Select-Object -First 1) } } } Function Test-SoftwareMeteringPrepDriver { - Param([Parameter(Mandatory=$true)]$Log) + Param([Parameter(Mandatory = $true)]$Log) # To execute function: if (Test-SoftwareMeteringPrepDriver -eq $false) {$restartCCMExec = $true} # Thanks to Paul Andrews for letting me know about this issue. # And Sherry Kissinger for a nice fix: https://mnscug.org/blogs/sherry-kissinger/481-configmgr-ccmrecentlyusedapps-blank-or-mtrmgr-log-with-startprepdriver-openservice-failed-with-error-issue @@ -2319,36 +2350,41 @@ Begin { # SCCM Client evaluation policies Function Get-SCCMPolicySourceUpdateMessage { $trigger = "{00000000-0000-0000-0000-000000000032}" - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID=$trigger} -ErrorAction SilentlyContinue | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID = $trigger } -ErrorAction SilentlyContinue | Out-Null + } else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'sms_client' -Name TriggerSchedule -ArgumentList @($trigger) -ErrorAction SilentlyContinue | Out-Null } } Function Get-SCCMPolicySendUnsentStateMessages { $trigger = "{00000000-0000-0000-0000-000000000111}" - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID=$trigger} -ErrorAction SilentlyContinue | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID = $trigger } -ErrorAction SilentlyContinue | Out-Null + } else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'sms_client' -Name TriggerSchedule -ArgumentList @($trigger) -ErrorAction SilentlyContinue | Out-Null } } Function Get-SCCMPolicyScanUpdateSource { $trigger = "{00000000-0000-0000-0000-000000000113}" - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID=$trigger} -ErrorAction SilentlyContinue | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID = $trigger } -ErrorAction SilentlyContinue | Out-Null + } else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'sms_client' -Name TriggerSchedule -ArgumentList @($trigger) -ErrorAction SilentlyContinue | Out-Null } } Function Get-SCCMPolicyHardwareInventory { $trigger = "{00000000-0000-0000-0000-000000000001}" - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID=$trigger} -ErrorAction SilentlyContinue | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID = $trigger } -ErrorAction SilentlyContinue | Out-Null + } else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'sms_client' -Name TriggerSchedule -ArgumentList @($trigger) -ErrorAction SilentlyContinue | Out-Null } } Function Get-SCCMPolicyMachineEvaluation { $trigger = "{00000000-0000-0000-0000-000000000022}" - if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID=$trigger} -ErrorAction SilentlyContinue | Out-Null } + if ($PowerShellVersion -ge 6) { Invoke-CimMethod -Namespace 'root\ccm' -ClassName 'sms_client' -MethodName TriggerSchedule -Arguments @{sScheduleID = $trigger } -ErrorAction SilentlyContinue | Out-Null + } else { Invoke-WmiMethod -Namespace 'root\ccm' -Class 'sms_client' -Name TriggerSchedule -ArgumentList @($trigger) -ErrorAction SilentlyContinue | Out-Null } } Function Get-Version { - $text = 'ConfigMgr Client Health Version ' +$Version + $text = 'ConfigMgr Client Health Version ' + $Version Write-Output $text Out-LogFile -Xml $xml -Text $text } @@ -2410,10 +2446,9 @@ Begin { $Database = 'ClientHealth' $FileLogLevel = ((Get-XMLConfigLoggingLevel).ToString()).ToLower() - $ConnectionString = "Server={0};Database={1};Integrated Security=True;" -f $SQLServer,$Database + $ConnectionString = "Server={0};Database={1};Integrated Security=True;" -f $SQLServer, $Database - try - { + try { $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $ConnectionString; $sqlConnection.Open(); $sqlConnection.Close(); @@ -2428,57 +2463,54 @@ Begin { $obj = $false; Write-Verbose "SQL connection test failed" } - finally {Write-Output $obj } + finally { Write-Output $obj } } # Invoke-SqlCmd2 - Created by Chad Miller function Invoke-Sqlcmd2 { [CmdletBinding()] param( - [Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance, - [Parameter(Position=1, Mandatory=$false)] [string]$Database, - [Parameter(Position=2, Mandatory=$false)] [string]$Query, - [Parameter(Position=3, Mandatory=$false)] [string]$Username, - [Parameter(Position=4, Mandatory=$false)] [string]$Password, - [Parameter(Position=5, Mandatory=$false)] [Int32]$QueryTimeout=600, - [Parameter(Position=6, Mandatory=$false)] [Int32]$ConnectionTimeout=15, - [Parameter(Position=7, Mandatory=$false)] [ValidateScript({test-path $_})] [string]$InputFile, - [Parameter(Position=8, Mandatory=$false)] [ValidateSet("DataSet", "DataTable", "DataRow")] [string]$As="DataRow" + [Parameter(Position = 0, Mandatory = $true)] [string]$ServerInstance, + [Parameter(Position = 1, Mandatory = $false)] [string]$Database, + [Parameter(Position = 2, Mandatory = $false)] [string]$Query, + [Parameter(Position = 3, Mandatory = $false)] [string]$Username, + [Parameter(Position = 4, Mandatory = $false)] [string]$Password, + [Parameter(Position = 5, Mandatory = $false)] [Int32]$QueryTimeout = 600, + [Parameter(Position = 6, Mandatory = $false)] [Int32]$ConnectionTimeout = 15, + [Parameter(Position = 7, Mandatory = $false)] [ValidateScript( { test-path $_ })] [string]$InputFile, + [Parameter(Position = 8, Mandatory = $false)] [ValidateSet("DataSet", "DataTable", "DataRow")] [string]$As = "DataRow" ) - if ($InputFile) - { + if ($InputFile) { $filePath = $(resolve-path $InputFile).path - $Query = [System.IO.File]::ReadAllText("$filePath") + $Query = [System.IO.File]::ReadAllText("$filePath") } - $conn=new-object System.Data.SqlClient.SQLConnection + $conn = new-object System.Data.SqlClient.SQLConnection - if ($Username) { $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout } - else { $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout } + if ($Username) { $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance, $Database, $Username, $Password, $ConnectionTimeout } + else { $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance, $Database, $ConnectionTimeout } - $conn.ConnectionString=$ConnectionString + $conn.ConnectionString = $ConnectionString #Following EventHandler is used for PRINT and RAISERROR T-SQL statements. Executed when -Verbose parameter specified by caller - if ($PSBoundParameters.Verbose) - { - $conn.FireInfoMessageEventOnUserErrors=$true - $handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {Write-Verbose "$($_)"} + if ($PSBoundParameters.Verbose) { + $conn.FireInfoMessageEventOnUserErrors = $true + $handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] { Write-Verbose "$($_)" } $conn.add_InfoMessage($handler) } $conn.Open() - $cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn) - $cmd.CommandTimeout=$QueryTimeout - $ds=New-Object system.Data.DataSet - $da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd) + $cmd = new-object system.Data.SqlClient.SqlCommand($Query, $conn) + $cmd.CommandTimeout = $QueryTimeout + $ds = New-Object system.Data.DataSet + $da = New-Object system.Data.SqlClient.SqlDataAdapter($cmd) [void]$da.fill($ds) $conn.Close() - switch ($As) - { - 'DataSet' { Write-Output ($ds) } + switch ($As) { + 'DataSet' { Write-Output ($ds) } 'DataTable' { Write-Output ($ds.Tables) } - 'DataRow' { Write-Output ($ds.Tables[0]) } + 'DataRow' { Write-Output ($ds.Tables[0]) } } } @@ -2499,13 +2531,13 @@ Begin { } $obj = New-Object PSObject -Property @{ - Hostname = $ComputerSystem.Name; - Manufacturer = $ComputerSystem.Manufacturer - Model = $Model - Operatingsystem = $OS.Caption; - Architecture = $OS.OSArchitecture; - Build = $OS.BuildNumber; - InstallDate = Get-SmallDateTime -Date ($OS.ConvertToDateTime($OS.InstallDate)) + Hostname = $ComputerSystem.Name; + Manufacturer = $ComputerSystem.Manufacturer + Model = $Model + Operatingsystem = $OS.Caption; + Architecture = $OS.OSArchitecture; + Build = $OS.BuildNumber; + InstallDate = Get-SmallDateTime -Date ($OS.ConvertToDateTime($OS.InstallDate)) LastLoggedOnUser = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\').LastLoggedOnUser; } @@ -2529,7 +2561,7 @@ Begin { Function Get-XMLConfigClientVersion { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Version'} | Select-Object -ExpandProperty '#text' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Version' } | Select-Object -ExpandProperty '#text' } if ($Webservice) { $obj = $Configuration.clientVersion @@ -2540,7 +2572,7 @@ Begin { Function Get-XMLConfigClientSitecode { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'SiteCode'} | Select-Object -ExpandProperty '#text' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'SiteCode' } | Select-Object -ExpandProperty '#text' } if ($Webservice ) { $obj = $Configuration.clientSitecode @@ -2551,9 +2583,9 @@ Begin { Function Get-XMLConfigClientDomain { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Domain'} | Select-Object -ExpandProperty '#text' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Domain' } | Select-Object -ExpandProperty '#text' } - if ($Webservice) { + if ($Webservice) { $obj = $Configuration.ClientDomain } Write-Output $obj @@ -2561,7 +2593,7 @@ Begin { Function Get-XMLConfigClientAutoUpgrade { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'AutoUpgrade'} | Select-Object -ExpandProperty '#text' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'AutoUpgrade' } | Select-Object -ExpandProperty '#text' } if ($Webservice) { $obj = $Configuration.clientAutoUpgrade @@ -2571,7 +2603,7 @@ Begin { Function Get-XMLConfigClientMaxLogSize { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Log'} | Select-Object -ExpandProperty 'MaxLogSize' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Log' } | Select-Object -ExpandProperty 'MaxLogSize' } if ($Webservice) { $obj = $Configuration.clientMaxLogSize @@ -2581,7 +2613,7 @@ Begin { Function Get-XMLConfigClientMaxLogHistory { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Log'} | Select-Object -ExpandProperty 'MaxLogHistory' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Log' } | Select-Object -ExpandProperty 'MaxLogHistory' } if ($Webservice) { $obj = $Configuration.clientMaxLogHistory @@ -2591,7 +2623,7 @@ Begin { Function Get-XMLConfigClientMaxLogSizeEnabled { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Log'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Log' } | Select-Object -ExpandProperty 'Enable' } if ($Webservice) { $obj = $Configuration.clientMaxLogSizeEnable @@ -2601,7 +2633,7 @@ Begin { Function Get-XMLConfigClientCache { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'CacheSize'} | Select-Object -ExpandProperty 'Value' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'CacheSize' } | Select-Object -ExpandProperty 'Value' } if ($Webservice) { $obj = $Configuration.clientCacheSize @@ -2611,7 +2643,7 @@ Begin { Function Get-XMLConfigClientCacheDeleteOrphanedData { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'CacheSize'} | Select-Object -ExpandProperty 'DeleteOrphanedData' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'CacheSize' } | Select-Object -ExpandProperty 'DeleteOrphanedData' } if ($Webservice) { $obj = $Configuration.remediationDeleteCacheOrphanedFiles @@ -2621,9 +2653,9 @@ Begin { Function Get-XMLConfigClientCacheEnable { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'CacheSize'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'CacheSize' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $obj = "True" } Write-Output $obj @@ -2631,19 +2663,19 @@ Begin { Function Get-XMLConfigClientShare { if ($config) { - $obj = $Xml.Configuration.Client | Where-Object {$_.Name -like 'Share'} | Select-Object -ExpandProperty '#text' -ErrorAction SilentlyContinue + $obj = $Xml.Configuration.Client | Where-Object { $_.Name -like 'Share' } | Select-Object -ExpandProperty '#text' -ErrorAction SilentlyContinue } if ($Webservice) { $obj = $Configuration.clientShare } - if(!($obj)){$obj=$global:ScriptPath} #If Client share is empty, default to the script folder. + if (!($obj)) { $obj = $global:ScriptPath } #If Client share is empty, default to the script folder. Write-Output $obj } Function Get-XMLConfigUpdatesShare { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Updates'} | Select-Object -ExpandProperty 'Share' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'Updates' } | Select-Object -ExpandProperty 'Share' } <# if ($Webservice) { @@ -2651,20 +2683,20 @@ Begin { } #> - If (!($obj)){$obj = Join-Path $global:ScriptPath "Updates"} + If (!($obj)) { $obj = Join-Path $global:ScriptPath "Updates" } Return $obj } Function Get-XMLConfigUpdatesEnable { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Updates'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'Updates' } | Select-Object -ExpandProperty 'Enable' } if ($Webservice) { $var = $Configuration.remediationUpdates switch ($var) { - 0 { $obj = "False"} # Disable - 1 { $obj = "True"} # Monitor - 2 { $obj = "True"} # Remediate + 0 { $obj = "False" } # Disable + 1 { $obj = "True" } # Monitor + 2 { $obj = "True" } # Remediate } } Write-Output $obj @@ -2672,13 +2704,14 @@ Begin { Function Get-XMLConfigUpdatesFix { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Updates'} | Select-Object -ExpandProperty 'Fix' } + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'Updates' } | Select-Object -ExpandProperty 'Fix' + } if ($Webservice) { $var = $Configuration.remediationUpdates switch ($var) { - 0 { $obj = "False"} # Disable - 1 { $obj = "False"} # Monitor - 2 { $obj = "True"} # Remediate + 0 { $obj = "False" } # Disable + 1 { $obj = "False" } # Monitor + 2 { $obj = "True" } # Remediate } } Write-Output $obj @@ -2686,7 +2719,7 @@ Begin { Function Get-XMLConfigLoggingShare { if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'File'} | Select-Object -ExpandProperty 'Share' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'File' } | Select-Object -ExpandProperty 'Share' } if ($Webservice) { $obj = $Configuration.logFileShare @@ -2698,7 +2731,7 @@ Begin { Function Get-XMLConfigLoggingLocalFile { if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'File'} | Select-Object -ExpandProperty 'LocalLogFile' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'File' } | Select-Object -ExpandProperty 'LocalLogFile' } if ($Webservice) { [string]$obj = $Configuration.localFiles @@ -2708,7 +2741,7 @@ Begin { Function Get-XMLConfigLoggingEnable { if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'File'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'File' } | Select-Object -ExpandProperty 'Enable' } if ($Webservice) { $obj = $Configuration.logFileShareEnable @@ -2719,7 +2752,7 @@ Begin { Function Get-XMLConfigLoggingMaxHistory { # Currently not configurable through console extension and webservice. TODO if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'File'} | Select-Object -ExpandProperty 'MaxLogHistory' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'File' } | Select-Object -ExpandProperty 'MaxLogHistory' } if ($Webservice) { $obj = 10 @@ -2729,13 +2762,13 @@ Begin { Function Get-XMLConfigLoggingLevel { if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'File'} | Select-Object -ExpandProperty 'Level' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'File' } | Select-Object -ExpandProperty 'Level' } if ($Webservice) { $ll = $Configuration.logLevel switch ($ll) { - 0 { $obj = "Full"} - 1 { $obj = "ClientInstall"} + 0 { $obj = "Full" } + 1 { $obj = "ClientInstall" } } } Write-Output $obj @@ -2743,13 +2776,13 @@ Begin { Function Get-XMLConfigLoggingTimeFormat { if ($config) { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'Time'} | Select-Object -ExpandProperty 'Format' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'Time' } | Select-Object -ExpandProperty 'Format' } - if ($Webservice) { + if ($Webservice) { $ltf = $Configuration.logTimeFormat switch ($ltf) { - 0 { $obj = "ClientLocal"} - 1 { $obj = "UTF"} + 0 { $obj = "ClientLocal" } + 1 { $obj = "UTF" } } } Write-Output $obj @@ -2758,13 +2791,13 @@ Begin { Function Get-XMLConfigPendingRebootApp { # TODO verify this function if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingReboot'} | Select-Object -ExpandProperty 'StartRebootApplication' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'PendingReboot' } | Select-Object -ExpandProperty 'StartRebootApplication' } - if ($Webservice) { + if ($Webservice) { $pr = $Configuration.remediationPendingReboot # misleading name for this variable, may change this in the future. switch ($pr) { - 0 { $obj = "False"} - 1 { $obj = "True"} + 0 { $obj = "False" } + 1 { $obj = "True" } } } Write-Output $obj @@ -2772,9 +2805,9 @@ Begin { Function Get-XMLConfigMaxRebootDays { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'MaxRebootDays'} | Select-Object -ExpandProperty 'Days' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'MaxRebootDays' } | Select-Object -ExpandProperty 'Days' } - if ($Webservice) { + if ($Webservice) { [float]$obj = $Configuration.remediationMaxRebootDays } Write-Output $obj @@ -2782,9 +2815,9 @@ Begin { Function Get-XMLConfigRebootApplication { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'RebootApplication'} | Select-Object -ExpandProperty 'Application' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'RebootApplication' } | Select-Object -ExpandProperty 'Application' } - if ($Webservice) { + if ($Webservice) { $obj = $Configuration.remediationRebootApplication } Write-Output $obj @@ -2793,7 +2826,7 @@ Begin { Function Get-XMLConfigRebootApplicationEnable { ### TODO implement in webservice if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'RebootApplication'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'RebootApplication' } | Select-Object -ExpandProperty 'Enable' } if ($webservice) { $obj = 'true' # TODO implement properly in webservice @@ -2804,14 +2837,14 @@ Begin { Function Get-XMLConfigDNSCheck { # TODO verify switch, skip test and monitor for console extension if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'DNSCheck'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'DNSCheck' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationDns switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, test enabled - 2 { $obj = "True"} # Fix, test enabled + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, test enabled + 2 { $obj = "True" } # Fix, test enabled } } Write-Output $obj @@ -2820,14 +2853,14 @@ Begin { Function Get-XMLConfigCcmSQLCELog { # TODO implement monitor mode if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'CcmSQLCELog'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'CcmSQLCELog' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationCcmSqlcelog switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor (this enables test for now. Monitor not implemented) - 2 { $obj = "True"} # Enable remediation + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor (this enables test for now. Monitor not implemented) + 2 { $obj = "True" } # Enable remediation } } @@ -2836,14 +2869,14 @@ Begin { Function Get-XMLConfigDNSFix { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'DNSCheck'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'DNSCheck' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationDns switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, so disable fix - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, so disable fix + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -2851,13 +2884,13 @@ Begin { Function Get-XMLConfigDrivers { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Drivers'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'Drivers' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationDrivers switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, enable test + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, enable test } } Write-Output $obj @@ -2865,7 +2898,7 @@ Begin { Function Get-XMLConfigPatchLevel { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PatchLevel'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'PatchLevel' } | Select-Object -ExpandProperty 'Enable' } if ($webservice) { # Default this to enabled. No reason not to log this @@ -2876,7 +2909,7 @@ Begin { Function Get-XMLConfigOSDiskFreeSpace { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'OSDiskFreeSpace'} | Select-Object -ExpandProperty '#text' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'OSDiskFreeSpace' } | Select-Object -ExpandProperty 'size' } if ($webservice) { # TODO consider implementing this in console extension / webservice. Relevance? @@ -2884,17 +2917,26 @@ Begin { } Write-Output $obj } - + Function Get-XMLConfigOSDiskFreeSpaceFix { + if ($Config) { + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'OSDiskFreeSpace' } | Select-Object -ExpandProperty 'Fix' + } + if ($Webservice) { + # TODO consider implementing this in console extension / webservice. Relevance? + $obj = "False" + } + Write-Output $obj + } Function Get-XMLConfigHardwareInventoryEnable { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'HardwareInventory'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'HardwareInventory' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationHardwareInventory switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, enable check - 2 { $obj = "True"} # Enable check + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, enable check + 2 { $obj = "True" } # Enable check } } Write-Output $obj @@ -2902,14 +2944,14 @@ Begin { Function Get-XMLConfigHardwareInventoryFix { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'HardwareInventory'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'HardwareInventory' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationHardwareInventory switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -2917,7 +2959,7 @@ Begin { Function Get-XMLConfigSoftwareMeteringEnable { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'SoftwareMetering'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'SoftwareMetering' } | Select-Object -ExpandProperty 'Enable' } if ($webservice) { @@ -2938,7 +2980,7 @@ Begin { Function Get-XMLConfigSoftwareMeteringFix { # TODO implement this check in console extension and webservice if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'SoftwareMetering'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'SoftwareMetering' } | Select-Object -ExpandProperty 'Fix' } if ($webservice) { $obj = "true" @@ -2949,7 +2991,7 @@ Begin { Function Get-XMLConfigHardwareInventoryDays { # TODO implement this check in console extension and webservice if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'HardwareInventory'} | Select-Object -ExpandProperty 'Days' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'HardwareInventory' } | Select-Object -ExpandProperty 'Days' } if ($webservice) { $obj = 30 @@ -2959,14 +3001,14 @@ Begin { Function Get-XMLConfigRemediationAdminShare { if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'AdminShare'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'AdminShare' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationAdminShare switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix # TODO implement monitoring of this check - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix # TODO implement monitoring of this check + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -2974,14 +3016,14 @@ Begin { Function Get-XMLConfigRemediationClientProvisioningMode { if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'ClientProvisioningMode'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'ClientProvisioningMode' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationClientProvisioningMode switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix # TODO implement monitoring of this check - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix # TODO implement monitoring of this check + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -2989,14 +3031,14 @@ Begin { Function Get-XMLConfigRemediationClientStateMessages { if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'ClientStateMessages'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'ClientStateMessages' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationClientStateMessages switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix # TODO implement monitoring of this check - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix # TODO implement monitoring of this check + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -3004,14 +3046,14 @@ Begin { Function Get-XMLConfigRemediationClientWUAHandler { if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'ClientWUAHandler'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'ClientWUAHandler' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationClientWuahandler switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix # TODO implement monitoring of this check - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix # TODO implement monitoring of this check + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -3020,7 +3062,7 @@ Begin { Function Get-XMLConfigRemediationClientWUAHandlerDays { # TODO implement days in console extension and webservice if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'ClientWUAHandler'} | Select-Object -ExpandProperty 'Days' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'ClientWUAHandler' } | Select-Object -ExpandProperty 'Days' } if ($webservice) { $obj = 30 @@ -3030,14 +3072,14 @@ Begin { Function Get-XMLConfigBITSCheck { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'BITSCheck'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'BITSCheck' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationBits switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, enable - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, enable + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -3045,41 +3087,41 @@ Begin { Function Get-XMLConfigBITSCheckFix { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'BITSCheck'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'BITSCheck' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationBits switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, disable fix - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, disable fix + 2 { $obj = "True" } # Enable fix } } Write-Output $obj } - Function Get-XMLConfigClientSettingsCheck { + Function Get-XMLConfigClientSettingsCheck { # TODO implement in console extension and webservice - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'ClientSettingsCheck'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'ClientSettingsCheck' } | Select-Object -ExpandProperty 'Enable' Write-Output $obj - } + } - Function Get-XMLConfigClientSettingsCheckFix { + Function Get-XMLConfigClientSettingsCheckFix { # TODO implement in console extension and webservice - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'ClientSettingsCheck'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'ClientSettingsCheck' } | Select-Object -ExpandProperty 'Fix' Write-Output $obj - } + } Function Get-XMLConfigWMI { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'WMI'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'WMI' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationWmi switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "True"} # Monitor, enable check - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "True" } # Monitor, enable check + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -3087,14 +3129,14 @@ Begin { Function Get-XMLConfigWMIRepairEnable { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'WMI'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'WMI' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationWmi switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix + 2 { $obj = "True" } # Enable fix } } Write-Output $obj @@ -3103,9 +3145,9 @@ Begin { Function Get-XMLConfigRefreshComplianceState { # Measured in days if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'RefreshComplianceState'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'RefreshComplianceState' } | Select-Object -ExpandProperty 'Enable' } - if ($Webservice) { + if ($Webservice) { $i = $Configuration.remediationRefreshComplianceState if ($i -eq 0) { $obj = "False" } else { $obj = "True" } @@ -3115,9 +3157,9 @@ Begin { Function Get-XMLConfigRefreshComplianceStateDays { if ($config) { - $obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'RefreshComplianceState'} | Select-Object -ExpandProperty 'Days' + $obj = $Xml.Configuration.Option | Where-Object { $_.Name -like 'RefreshComplianceState' } | Select-Object -ExpandProperty 'Days' } - if ($Webservice) { + if ($Webservice) { $obj = $Configuration.remediationRefreshComplianceState } Write-Output $obj @@ -3125,26 +3167,26 @@ Begin { Function Get-XMLConfigRemediationClientCertificate { if ($config) { - $obj = $Xml.Configuration.Remediation | Where-Object {$_.Name -like 'ClientCertificate'} | Select-Object -ExpandProperty 'Fix' + $obj = $Xml.Configuration.Remediation | Where-Object { $_.Name -like 'ClientCertificate' } | Select-Object -ExpandProperty 'Fix' } - if ($Webservice) { + if ($Webservice) { $s = $Configuration.remediationClientCertificate switch ($s) { - 0 { $obj = "False"} # Test disabled - 1 { $obj = "False"} # Monitor, disable fix # TODO implement in script - 2 { $obj = "True"} # Enable fix + 0 { $obj = "False" } # Test disabled + 1 { $obj = "False" } # Monitor, disable fix # TODO implement in script + 2 { $obj = "True" } # Enable fix } } Write-Output $obj } Function Get-XMLConfigSQLServer { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'SQL'} | Select-Object -ExpandProperty 'Server' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'SQL' } | Select-Object -ExpandProperty 'Server' Write-Output $obj } Function Get-XMLConfigSQLLoggingEnable { - $obj = $Xml.Configuration.Log | Where-Object {$_.Name -like 'SQL'} | Select-Object -ExpandProperty 'Enable' + $obj = $Xml.Configuration.Log | Where-Object { $_.Name -like 'SQL' } | Select-Object -ExpandProperty 'Enable' Write-Output $obj } @@ -3155,10 +3197,10 @@ Begin { Function GetComputerInfo { $info = Get-Info | Select-Object HostName, OperatingSystem, Architecture, Build, InstallDate, Manufacturer, Model, LastLoggedOnUser #$text = 'Computer info'+ "`n" - $text = 'Hostname: ' +$info.HostName + $text = 'Hostname: ' + $info.HostName Write-Output $text #Out-LogFile -Xml $xml $text - $text = 'Operatingsystem: ' +$info.OperatingSystem + $text = 'Operatingsystem: ' + $info.OperatingSystem Write-Output $text #Out-LogFile -Xml $xml $text $text = 'Architecture: ' + $info.Architecture @@ -3228,7 +3270,7 @@ Begin { } Function New-LogObject { - # Write-Verbose "Start New-LogObject" + # Write-Verbose "Start New-LogObject" if ($PowerShellVersion -ge 6) { $OS = Get-CimInstance -class Win32_OperatingSystem @@ -3283,57 +3325,59 @@ Begin { if ($PSBuild -le 0) { $PSBuild = $null } $UBR = Get-UBR $BITS = $null - $ClientSettings = $null + $ClientSettings = $null + $OSDiskCleanup = $null $obj = New-Object PSObject -Property @{ - Hostname = $Hostname - Operatingsystem = $OperatingSystem - Architecture = $Architecture - Build = $Build - Manufacturer = $Manufacturer - Model = $Model - InstallDate = $InstallDate - OSUpdates = $null - LastLoggedOnUser = $LastLoggedOnUser - ClientVersion = $ClientVersion - PSVersion = $PSVersion - PSBuild = $PSBuild - Sitecode = $Sitecode - Domain = $Domain - MaxLogSize = $MaxLogSize - MaxLogHistory = $MaxLogHistory - CacheSize = $CacheSize - ClientCertificate = $ClientCertificate - ProvisioningMode = $ProvisioningMode - DNS = $DNS - Drivers = $Drivers - Updates = $Updates - PendingReboot = $PendingReboot - LastBootTime = $LastBootTime - OSDiskFreeSpace = $OSDiskFreeSpace - Services = $Services - AdminShare = $AdminShare - StateMessages = $StateMessages - WUAHandler = $WUAHandler - WMI = $WMI + Hostname = $Hostname + Operatingsystem = $OperatingSystem + Architecture = $Architecture + Build = $Build + Manufacturer = $Manufacturer + Model = $Model + InstallDate = $InstallDate + OSUpdates = $null + LastLoggedOnUser = $LastLoggedOnUser + ClientVersion = $ClientVersion + PSVersion = $PSVersion + PSBuild = $PSBuild + Sitecode = $Sitecode + Domain = $Domain + MaxLogSize = $MaxLogSize + MaxLogHistory = $MaxLogHistory + CacheSize = $CacheSize + ClientCertificate = $ClientCertificate + ProvisioningMode = $ProvisioningMode + DNS = $DNS + Drivers = $Drivers + Updates = $Updates + PendingReboot = $PendingReboot + LastBootTime = $LastBootTime + OSDiskFreeSpace = $OSDiskFreeSpace + Services = $Services + AdminShare = $AdminShare + StateMessages = $StateMessages + WUAHandler = $WUAHandler + WMI = $WMI RefreshComplianceState = $RefreshComplianceState - ClientInstalled = $null - Version = $Version - Timestamp = $smallDateTime - HWInventory = $null - SWMetering = $null - ClientSettings = $null - BITS = $BITS - PatchLevel = $UBR - ClientInstalledReason = $null - RebootApp = $RebootApp + ClientInstalled = $null + Version = $Version + Timestamp = $smallDateTime + HWInventory = $null + SWMetering = $null + ClientSettings = $ClientSettings + BITS = $BITS + PatchLevel = $UBR + ClientInstalledReason = $null + RebootApp = $RebootApp + OSDiskCleanup = $OSDiskCleanup } Write-Output $obj - # Write-Verbose "End New-LogObject" + # Write-Verbose "End New-LogObject" } Function Get-SmallDateTime { - Param([Parameter(Mandatory=$false)]$Date) + Param([Parameter(Mandatory = $false)]$Date) #Write-Verbose "Start Get-SmallDateTime" $UTC = (Get-XMLConfigLoggingTimeFormat).ToLower() @@ -3360,8 +3404,8 @@ Begin { Function Update-SQL { Param( - [Parameter(Mandatory=$true)]$Log, - [Parameter(Mandatory=$false)]$Table + [Parameter(Mandatory = $true)]$Log, + [Parameter(Mandatory = $false)]$Table ) Write-Verbose "Start Update-SQL" @@ -3374,11 +3418,11 @@ Begin { if ($null -ne $log.OSUpdates) { # UPDATE - $q1 = "OSUpdates='"+$log.OSUpdates+"', " + $q1 = "OSUpdates='" + $log.OSUpdates + "', " # INSERT INTO $q2 = "OSUpdates, " # VALUES - $q3 = "'"+$log.OSUpdates+"', " + $q3 = "'" + $log.OSUpdates + "', " } else { $q1 = $null @@ -3388,11 +3432,11 @@ Begin { if ($null -ne $log.ClientInstalled) { # UPDATE - $q10 = "ClientInstalled='"+$log.ClientInstalled+"', " + $q10 = "ClientInstalled='" + $log.ClientInstalled + "', " # INSERT INTO $q20 = "ClientInstalled, " # VALUES - $q30 = "'"+$log.ClientInstalled+"', " + $q30 = "'" + $log.ClientInstalled + "', " } else { $q10 = $null @@ -3400,17 +3444,17 @@ Begin { $q30 = $null } - #ADD ClientSettings.log... - $query= "begin tran - if exists (SELECT * FROM $table WITH (updlock,serializable) WHERE Hostname='"+$log.Hostname+"') + #ADD ClientSettings.log... + $query = "begin tran + if exists (SELECT * FROM $table WITH (updlock,serializable) WHERE Hostname='" + $log.Hostname + "') begin - UPDATE $table SET Operatingsystem='"+$log.Operatingsystem+"', Architecture='"+$log.Architecture+"', Build='"+$log.Build+"', Manufacturer='"+$log.Manufacturer+"', Model='"+$log.Model+"', InstallDate='"+$log.InstallDate+"', $q1 LastLoggedOnUser='"+$log.LastLoggedOnUser+"', ClientVersion='"+$log.ClientVersion+"', PSVersion='"+$log.PSVersion+"', PSBuild='"+$log.PSBuild+"', Sitecode='"+$log.Sitecode+"', Domain='"+$log.Domain+"', MaxLogSize='"+$log.MaxLogSize+"', MaxLogHistory='"+$log.MaxLogHistory+"', CacheSize='"+$log.CacheSize+"', ClientCertificate='"+$log.ClientCertificate+"', ProvisioningMode='"+$log.ProvisioningMode+"', DNS='"+$log.DNS+"', Drivers='"+$log.Drivers+"', Updates='"+$log.Updates+"', PendingReboot='"+$log.PendingReboot+"', LastBootTime='"+$log.LastBootTime+"', OSDiskFreeSpace='"+$log.OSDiskFreeSpace+"', Services='"+$log.Services+"', AdminShare='"+$log.AdminShare+"', StateMessages='"+$log.StateMessages+"', WUAHandler='"+$log.WUAHandler+"', WMI='"+$log.WMI+"', RefreshComplianceState='"+$log.RefreshComplianceState+"', HWInventory='"+$log.HWInventory+"', Version='"+$Version+"', $q10 Timestamp='"+$smallDateTime+"', SWMetering='"+$log.SWMetering+"', BITS='"+$log.BITS+"', PatchLevel='"+$Log.PatchLevel+"', ClientInstalledReason='"+$log.ClientInstalledReason+"' - WHERE Hostname = '"+$log.Hostname+"' + UPDATE $table SET Operatingsystem='" + $log.Operatingsystem + "', Architecture='" + $log.Architecture + "', Build='" + $log.Build + "', Manufacturer='" + $log.Manufacturer + "', Model='" + $log.Model + "', InstallDate='" + $log.InstallDate + "', $q1 LastLoggedOnUser='" + $log.LastLoggedOnUser + "', ClientVersion='" + $log.ClientVersion + "', PSVersion='" + $log.PSVersion + "', PSBuild='" + $log.PSBuild + "', Sitecode='" + $log.Sitecode + "', Domain='" + $log.Domain + "', MaxLogSize='" + $log.MaxLogSize + "', MaxLogHistory='" + $log.MaxLogHistory + "', CacheSize='" + $log.CacheSize + "', ClientCertificate='" + $log.ClientCertificate + "', ProvisioningMode='" + $log.ProvisioningMode + "', DNS='" + $log.DNS + "', Drivers='" + $log.Drivers + "', Updates='" + $log.Updates + "', PendingReboot='" + $log.PendingReboot + "', LastBootTime='" + $log.LastBootTime + "', OSDiskFreeSpace='" + $log.OSDiskFreeSpace + "', Services='" + $log.Services + "', AdminShare='" + $log.AdminShare + "', StateMessages='" + $log.StateMessages + "', WUAHandler='" + $log.WUAHandler + "', WMI='" + $log.WMI + "', RefreshComplianceState='" + $log.RefreshComplianceState + "', HWInventory='" + $log.HWInventory + "', Version='" + $Version + "', $q10 Timestamp='" + $smallDateTime + "', SWMetering='" + $log.SWMetering + "', BITS='" + $log.BITS + "', PatchLevel='" + $Log.PatchLevel + "', ClientInstalledReason='" + $log.ClientInstalledReason + "', OSDiskCleanup='" + $log.OSDiskCleanup + "' + WHERE Hostname = '" + $log.Hostname + "' end else begin - INSERT INTO $table (Hostname, Operatingsystem, Architecture, Build, Manufacturer, Model, InstallDate, $q2 LastLoggedOnUser, ClientVersion, PSVersion, PSBuild, Sitecode, Domain, MaxLogSize, MaxLogHistory, CacheSize, ClientCertificate, ProvisioningMode, DNS, Drivers, Updates, PendingReboot, LastBootTime, OSDiskFreeSpace, Services, AdminShare, StateMessages, WUAHandler, WMI, RefreshComplianceState, HWInventory, Version, $q20 Timestamp, SWMetering, BITS, PatchLevel, ClientInstalledReason) - VALUES ('"+$log.Hostname+"', '"+$log.Operatingsystem+"', '"+$log.Architecture+"', '"+$log.Build+"', '"+$log.Manufacturer+"', '"+$log.Model+"', '"+$log.InstallDate+"', $q3 '"+$log.LastLoggedOnUser+"', '"+$log.ClientVersion+"', '"+$log.PSVersion+"', '"+$log.PSBuild+"', '"+$log.Sitecode+"', '"+$log.Domain+"', '"+$log.MaxLogSize+"', '"+$log.MaxLogHistory+"', '"+$log.CacheSize+"', '"+$log.ClientCertificate+"', '"+$log.ProvisioningMode+"', '"+$log.DNS+"', '"+$log.Drivers+"', '"+$log.Updates+"', '"+$log.PendingReboot+"', '"+$log.LastBootTime+"', '"+$log.OSDiskFreeSpace+"', '"+$log.Services+"', '"+$log.AdminShare+"', '"+$log.StateMessages+"', '"+$log.WUAHandler+"', '"+$log.WMI+"', '"+$log.RefreshComplianceState+"', '"+$log.HWInventory+"', '"+$log.Version+"', $q30 '"+$smallDateTime+"', '"+$log.SWMetering+"', '"+$log.BITS+"', '"+$Log.PatchLevel+"', '"+$Log.ClientInstalledReason+"') + INSERT INTO $table (Hostname, Operatingsystem, Architecture, Build, Manufacturer, Model, InstallDate, $q2 LastLoggedOnUser, ClientVersion, PSVersion, PSBuild, Sitecode, Domain, MaxLogSize, MaxLogHistory, CacheSize, ClientCertificate, ProvisioningMode, DNS, Drivers, Updates, PendingReboot, LastBootTime, OSDiskFreeSpace, Services, AdminShare, StateMessages, WUAHandler, WMI, RefreshComplianceState, HWInventory, Version, $q20 Timestamp, SWMetering, BITS, PatchLevel, ClientInstalledReason,OSDiskCleanup) + VALUES ('" + $log.Hostname + "', '" + $log.Operatingsystem + "', '" + $log.Architecture + "', '" + $log.Build + "', '" + $log.Manufacturer + "', '" + $log.Model + "', '" + $log.InstallDate + "', $q3 '" + $log.LastLoggedOnUser + "', '" + $log.ClientVersion + "', '" + $log.PSVersion + "', '" + $log.PSBuild + "', '" + $log.Sitecode + "', '" + $log.Domain + "', '" + $log.MaxLogSize + "', '" + $log.MaxLogHistory + "', '" + $log.CacheSize + "', '" + $log.ClientCertificate + "', '" + $log.ProvisioningMode + "', '" + $log.DNS + "', '" + $log.Drivers + "', '" + $log.Updates + "', '" + $log.PendingReboot + "', '" + $log.LastBootTime + "', '" + $log.OSDiskFreeSpace + "', '" + $log.Services + "', '" + $log.AdminShare + "', '" + $log.StateMessages + "', '" + $log.WUAHandler + "', '" + $log.WMI + "', '" + $log.RefreshComplianceState + "', '" + $log.HWInventory + "', '" + $log.Version + "', $q30 '" + $smallDateTime + "', '" + $log.SWMetering + "', '" + $log.BITS + "', '" + $Log.PatchLevel + "', '" + $Log.ClientInstalledReason + "','" + $log.OSDiskCleanup + "') end commit tran" @@ -3426,9 +3470,9 @@ Begin { Function Update-LogFile { Param( - [Parameter(Mandatory=$true)]$Log, - [Parameter(Mandatory=$false)]$Mode - ) + [Parameter(Mandatory = $true)]$Log, + [Parameter(Mandatory = $false)]$Mode + ) # Start the logfile Write-Verbose "Start Update-LogFile" #$share = Get-XMLConfigLoggingShare @@ -3437,11 +3481,11 @@ Begin { $logfile = $logfile = Get-LogFileName Test-LogFileHistory -Logfile $logfile $text = "<--- ConfigMgr Client Health Check starting --->" - $text += $log | Select-Object Hostname, Operatingsystem, Architecture, Build, Model, InstallDate, OSUpdates, LastLoggedOnUser, ClientVersion, PSVersion, PSBuild, SiteCode, Domain, MaxLogSize, MaxLogHistory, CacheSize, Certificate, ProvisioningMode, DNS, PendingReboot, LastBootTime, OSDiskFreeSpace, Services, AdminShare, StateMessages, WUAHandler, WMI, RefreshComplianceState, ClientInstalled, Version, Timestamp, HWInventory, SWMetering, BITS, ClientSettings, PatchLevel, ClientInstalledReason | Out-String - $text = $text.replace("`t","") - $text = $text.replace(" ","") - $text = $text.replace(" :",":") - $text = $text -creplace '(?m)^\s*\r?\n','' + $text += $log | Select-Object Hostname, Operatingsystem, Architecture, Build, Model, InstallDate, OSUpdates, LastLoggedOnUser, ClientVersion, PSVersion, PSBuild, SiteCode, Domain, MaxLogSize, MaxLogHistory, CacheSize, Certificate, ProvisioningMode, DNS, PendingReboot, LastBootTime, OSDiskFreeSpace, Services, AdminShare, StateMessages, WUAHandler, WMI, RefreshComplianceState, ClientInstalled, Version, Timestamp, HWInventory, SWMetering, BITS, ClientSettings, PatchLevel, ClientInstalledReason, OSDiskCleanup | Out-String + $text = $text.replace("`t", "") + $text = $text.replace(" ", "") + $text = $text.replace(" :", ":") + $text = $text -creplace '(?m)^\s*\r?\n', '' if ($Mode -eq 'Local') { Out-LogFile -Xml $xml -Text $text -Mode $Mode } elseif ($Mode -eq 'ClientInstalledFailed') { Out-LogFile -Xml $xml -Text $text -Mode $Mode } @@ -3490,30 +3534,30 @@ Begin { $AS = $Configuration.remediationAdminShare switch ($AS) { - 0 { $AdminShare = "False"; break} #Disable - 1 { $AdminShare = "True"; break} #Monitor - 2 { $AdminShare = "True"; break} #Enable + 0 { $AdminShare = "False"; break } #Disable + 1 { $AdminShare = "True"; break } #Monitor + 2 { $AdminShare = "True"; break } #Enable } $CPM = $Configuration.remediationClientProvisioningMode switch ($CPM) { - 0 { $ClientProvisioningMode = "False"; break} #Disable - 1 { $ClientProvisioningMode = "True"; break} #Monitor - 2 { $ClientProvisioningMode = "True"; break} #Enable + 0 { $ClientProvisioningMode = "False"; break } #Disable + 1 { $ClientProvisioningMode = "True"; break } #Monitor + 2 { $ClientProvisioningMode = "True"; break } #Enable } $CSM = $Configuration.remediationClientStateMessages switch ($CSM) { - 0 { $ClientStateMessages = "False"; break} #Disable - 1 { $ClientStateMessages = "True"; break} #Monitor - 2 { $ClientStateMessages = "True"; break} #Enable + 0 { $ClientStateMessages = "False"; break } #Disable + 1 { $ClientStateMessages = "True"; break } #Monitor + 2 { $ClientStateMessages = "True"; break } #Enable } $CWUA = $Configuration.remediationClientWuahandler switch ($CWUA) { - 0 { $ClientWUAHandler = "False"; break} #Disable - 1 { $ClientWUAHandler = "True"; break} #Monitor - 2 { $ClientWUAHandler = "True"; break} #Enable + 0 { $ClientWUAHandler = "False"; break } #Disable + 1 { $ClientWUAHandler = "True"; break } #Monitor + 2 { $ClientWUAHandler = "True"; break } #Enable } $LogShare = $Configuration.logFileShare @@ -3530,8 +3574,7 @@ Begin { Process { Write-Verbose "Starting precheck. Determing if script will run or not." # Veriy script is running with administrative priveleges. - If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) - { + If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { $text = 'ERROR: Powershell not running as Administrator! Client Health aborting.' Out-LogFile -Xml $Xml -Text $text Write-Error $text @@ -3552,11 +3595,11 @@ Process { $TSName = $tsenv.Value("_SMSTSAdvertID") Write-Host "Task sequence $TSName is active executing on computer. ConfigMgr Client Health will not execute." Exit 1 - } - else { - $StartupText2 = "ConfigMgr Client Health " +$Version+ " starting." + } + else { + $StartupText2 = "ConfigMgr Client Health " + $Version + " starting." Write-Host $StartupText2 - } + } } @@ -3575,8 +3618,8 @@ Process { $FileLogging = $Configuration.logFileShareEnable.ToString().ToLower() $FLL = $Configuration.logLevel.ToString().ToLower() switch ($FLL) { - 0 { $FileLogLevel = "Full"} - 1 { $FileLogLevel = "ClientInstall"} + 0 { $FileLogLevel = "Full" } + 1 { $FileLogLevel = "ClientInstall" } } $SQLLogging = "true" @@ -3589,8 +3632,8 @@ Process { $LastRunRegistryValueName = "LastRun" #Get the last run from the registry, defaulting to the minimum date value if the script has never ran. - try{[datetime]$LastRun = Get-RegistryValue -Path $RegistryKey -Name $LastRunRegistryValueName} - catch{$LastRun=[datetime]::MinValue} + try { [datetime]$LastRun = Get-RegistryValue -Path $RegistryKey -Name $LastRunRegistryValueName } + catch { $LastRun = [datetime]::MinValue } Write-Output "Script last ran: $($LastRun)" Write-Verbose "Testing if log files are bigger than max history for logfiles." @@ -3684,7 +3727,7 @@ Process { if (Get-XMLConfigSoftwareMeteringEnable -like 'True') { Write-Verbose "Testing software metering prep driver check" - if ((Test-SoftwareMeteringPrepDriver -Log $Log) -eq $false) {$restartCCMExec = $true} + if ((Test-SoftwareMeteringPrepDriver -Log $Log) -eq $false) { $restartCCMExec = $true } } Write-Verbose 'Validating DNS...' @@ -3698,12 +3741,12 @@ Process { } Write-Verbose 'Validating ClientSettings' - If (Get-XMLConfigClientSettingsCheck -like 'True') { + If (Get-XMLConfigClientSettingsCheck -like 'True') { Test-ClientSettingsConfiguration -Log $log - } + } if (($ClientWUAHandler -like 'True') -eq $true) { - Write-Verbose 'Validating Windows Update Scan not broken by bad group policy...' + Write-Verbose 'Validating Windows Update Scan not broken by bad group policy...' $days = Get-XMLConfigRemediationClientWUAHandlerDays Test-RegistryPol -Days $days -log $log -StartTime $LastRun @@ -3716,16 +3759,16 @@ Process { } Write-Verbose 'Validating Admin$ and C$ are shared...' - if (($AdminShare -like 'True') -eq $true) {Test-AdminShare -log $log} + if (($AdminShare -like 'True') -eq $true) { Test-AdminShare -log $log } Write-Verbose 'Testing that all devices have functional drivers.' - if ((Get-XMLConfigDrivers -like 'True') -eq $true) {Test-MissingDrivers -Log $log} + if ((Get-XMLConfigDrivers -like 'True') -eq $true) { Test-MissingDrivers -Log $log } $UpdatesEnabled = Get-XMLConfigUpdatesEnable if ($UpdatesEnabled -like 'True') { - Write-Verbose 'Validating required updates are installed...' - Test-Update -Log $log - } + Write-Verbose 'Validating required updates are installed...' + Test-Update -Log $log + } Write-Verbose "Validating $env:SystemDrive free diskspace (Only warning, no remediation)..." Test-DiskSpace @@ -3752,7 +3795,7 @@ Process { Update-SCCMLogFile Start-Service -Name CcmExec } - else {Restart-Service -Name CcmExec} + else { Restart-Service -Name CcmExec } $Log.MaxLogSize = Get-ClientMaxLogSize $Log.MaxLogHistory = Get-ClientMaxLogHistory @@ -3767,8 +3810,8 @@ Process { Write-Verbose 'Validating pending reboot...' Test-PendingReboot -log $log Write-Verbose 'Getting last reboot time' - if ($config) {Get-LastReboot -Xml $xml} - if ($Webservice) {Get-LastReboot} + if ($config) { Get-LastReboot -Xml $xml } + if ($Webservice) { Get-LastReboot } if (Get-XMLConfigClientCacheDeleteOrphanedData -like "true") { Write-Verbose "Removing orphaned ccm client cache items." diff --git a/CreateDatabase.sql b/CreateDatabase.sql index caa8265..e57a6ac 100644 --- a/CreateDatabase.sql +++ b/CreateDatabase.sql @@ -65,7 +65,8 @@ CREATE TABLE dbo.Clients SWMetering varchar(50), BITS varchar(50), PatchLevel int, - ClientInstalledReason varchar(200) + ClientInstalledReason varchar(200), + OSDiskCleanup varchar(50) ) else @@ -77,6 +78,7 @@ IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[C IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[Clients]') AND name = 'PatchLevel') ALTER TABLE dbo.Clients ADD PatchLevel int IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[Clients]') AND name = 'ClientInstalledReason') ALTER TABLE dbo.Clients ADD ClientInstalledReason varchar(200) IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[Clients]') AND name = 'RefreshComplianceState') ALTER TABLE dbo.Clients ADD RefreshComplianceState smalldatetime +IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[Clients]') AND name = 'OSDiskCleanup') ALTER TABLE dbo.Clients ADD OSDiskCleanup varchar(50) -- Modify columns if needed @@ -97,13 +99,13 @@ GO begin tran if exists (SELECT * FROM dbo.Configuration WITH (updlock,serializable) WHERE Name='ClientHealth') begin - IF EXISTS (SELECT * FROM dbo.Configuration WITH (updlock,serializable) WHERE Name='ClientHealth' AND Version < '0.7.5') - UPDATE dbo.Configuration SET Version='0.7.5' WHERE Name = 'ClientHealth' + IF EXISTS (SELECT * FROM dbo.Configuration WITH (updlock,serializable) WHERE Name='ClientHealth' AND Version < '0.7.6') + UPDATE dbo.Configuration SET Version='0.7.6' WHERE Name = 'ClientHealth' end else begin INSERT INTO dbo.Configuration (Name, Version) - VALUES ('ClientHealth', '0.7.5') + VALUES ('ClientHealth', '0.7.6') end commit tran diff --git a/config.xml b/config.xml index d6a87bf..745de1e 100644 --- a/config.xml +++ b/config.xml @@ -27,7 +27,7 @@ +