Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 104 additions & 1 deletion ConfigMgrClientHealth.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,99 @@ Begin {
}
}

## Function provided by @CodyMathis123 ##
Function Get-CHini {
<#
.SYNOPSIS
Reads an ini file and returns back the value of the provided key
.DESCRIPTION
Parses through a provided ini file and finds the value of a key under a particular section of the file
.EXAMPLE
Get-CHINI -parameter "value"
.EXAMPLE
Get-CHINI -File "c:\Windows\smscfg.ini" -Section "Configuration - Client Properties" -Key "SID"
.PARAMETER File
Full path to desired ini file
.PARAMETER Section
Section name from the ini file where the requested key is located
.PARAMETER Key
Key name of requested value
#>
param
(
[Parameter(Mandatory = $True)]
[ValidateScript( { Test-Path -Path $_ -PathType Leaf })]
[ValidatePattern('.ini$')]
[string]$File,

[Parameter(Mandatory = $True,
ValueFromPipelineByPropertyName = $True)]
[string]$Section,

[Parameter(Mandatory = $True,
ValueFromPipelineByPropertyName = $True)]
[string]$Key

)
$InitialMessage = [string]::Format("Parsing [File = '{0}'] for [Key = '{1}'] under [Section = '{2}']", $File, $Key, $Section)
Write-Verbose $InitialMessage
[object]$INI = New-Object -TypeName psobject

switch -regex -file $File {
'^\[(.+)\]' {
#Section
$INISection = $matches[1]
}
'(.+?)\s*=(.*)' {
#Key
$name, $value = $matches[1..2]
$INI | Add-Member -MemberType NoteProperty -Name ('{0}.{1}' -f $INISection, $name) -Value $value
}
}

#$Value = $INI[$Section][$Key]
$Value = $INI.(('{0}.{1}' -f $Section, $key))
If ($null -eq $Value) {
Write-Warning "$Key value is blank"
}
Else {
Write-Verbose "$Key value found"
Write-Verbose "$Key = $Value"
return $Value
}
}

## Function provided by @CodyMathis123 ##
Function Get-CMClientGUID {
Param([Parameter(Mandatory=$true)]$Log)
<#
Code from Cody Mathis
Checks WMI first, then parses SMSCFG.INI as a fallback to determine the current GUID associated with the machine.
#>
Try {
$return = $null
$GUID = Get-WmiObject -Namespace root\ccm -Query "Select ClientID from CCM_Client" | Select-Object -ExpandProperty ClientID
if ([string]::IsNullOrWhiteSpace($GUID)) {
Write-Warning 'Failed to get CM Client GUID from WMI - falling back to parsing smscfg.ini'
throw 'Failed to get CM Client GUID from WMI - falling back to parsing smscfg.ini'
}
else {
Write-Output "Client GUID: $GUID"
$log.CMClientGUID = $GUID
}
}
catch {
$GUID = Get-CHini -File "$env:windir\smscfg.ini" -Section 'Configuration - Client Properties' -Key 'SMS Unique Identifier'
if ([string]::IsNullOrWhiteSpace($GUID)) {
Write-Warning 'Failed to get CM Client GUID from smscfg.ini'
}
else {
Write-Output "Client GUID: $GUID"
$log.CMClientGUID = $GUID
}
}
}

Function Update-State {
Write-Verbose "Start Update-State"
$SCCMUpdatesStore = New-Object -ComObject Microsoft.CCM.UpdatesStore
Expand Down Expand Up @@ -2888,6 +2981,12 @@ Begin {
Write-Output $obj
}

Function Get-XMLConfigGUIDCheck {
if ($config) {
$obj = $Xml.Configuration.Option | Where-Object {$_.Name -like 'ClientGUIDCheck'} | Select-Object -ExpandProperty 'Enable'
}
Write-Output $obj
}


# End Getters - XML config file
Expand Down Expand Up @@ -2996,6 +3095,7 @@ Begin {
$DNS = 'Unknown'
$Drivers = 'Unknown'
$ClientCertificate = 'Unknown'
$CMClientGUID = 'Unknown'
$PendingReboot = 'Unknown'
$RebootApp = 'Unknown'
if ($PowerShellVersion -ge 6) { $LastBootTime = Get-SmallDateTime -Date ($OS.LastBootUpTime) }
Expand Down Expand Up @@ -3038,6 +3138,7 @@ Begin {
ClientCertificate = $ClientCertificate
ProvisioningMode = $ProvisioningMode
DNS = $DNS
CMClientGUID = $CMClientGUID
Drivers = $Drivers
Updates = $Updates
PendingReboot = $PendingReboot
Expand Down Expand Up @@ -3169,7 +3270,7 @@ 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 += $log | Select-Object Hostname, Operatingsystem, Architecture, Build, Model, InstallDate, OSUpdates, LastLoggedOnUser, ClientVersion, CMClientGUID, 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(" :",":")
Expand Down Expand Up @@ -3353,6 +3454,8 @@ Process {
if ((Get-XMLConfigRemediationClientCertificate -like 'True') -eq $true) { Test-CCMCertificateError -Log $Log }
if (Get-XMLConfigHardwareInventoryEnable -like 'True') { Test-SCCMHardwareInventoryScan -Log $log }

Write-Verbose 'Gathering Client GUID...'
if ((Get-XMLConfigGUIDCheck -like 'True' ) -eq $true) { Get-CMClientGUID -Log $log }

if (Get-XMLConfigSoftwareMeteringEnable -like 'True') {
Write-Verbose "Testing software metering prep driver check"
Expand Down
1 change: 1 addition & 0 deletions CreateDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,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 = 'CMClientGUID') ALTER TABLE dbo.Clients ADD CMClientGUID varchar(41)


-- Modify columns if needed
Expand Down
1 change: 1 addition & 0 deletions config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<Option Name="SoftwareMetering" Fix="True" Enable="True" />
<Option Name="WMI" Fix="True" Enable="True"/>
<Option Name="RefreshComplianceState" Days="30" Enable="True"/>
<Option Name="ClientGUIDCheck" Enable="True" />
<Service Name="BITS" StartupType="Automatic (Delayed Start)" State="Running" Uptime=""/>
<Service Name="winmgmt" StartupType="Automatic" State="Running" Uptime=""/>
<Service Name="wuauserv" StartupType="Automatic (Delayed Start)" State="Running" Uptime=""/>
Expand Down