Public/Set-WmiInstance.ps1
#region Function Set-WmiInstance Function Set-WmiInstance { <# .SYNOPSIS This function is used to modify a WMI Instance. .DESCRIPTION This function is used to modify or optionaly creating a WMI Instance if it does not exist using CIM. .PARAMETER Namespace The Class Namespace. The Default is ROOT\cimv2. .PARAMETER ClassName The Class Name. .PARAMETER Key The Properties that are used as keys (Optional). .PARAMETER PropertySearch The Class Instance Properties and Values to find. .PARAMETER Property The Class Instance Properties and Values to set. .PARAMETER CreateInstance Switch for creating the instance if it does not exist. Default is $false .EXAMPLE [hashtable]$PropertySearch = @{ 'ServerPort' = '99' 'ServerIP' = '10.10.10.10' } [hashtable]$Property = @{ 'ServerPort' = '88' 'ServerIP' = '11.11.11.11' 'Source' = 'File1' 'Date' = $(Get-Date) } Set-WmiInstance -Namespace 'ROOT' -ClassName 'SCCMZone' -Key 'File1' -PropertySearch $PropertySearch -Property $Property .EXAMPLE Set-WmiInstance -Namespace 'ROOT' -ClassName 'SCCMZone' -Key 'File1' -Property $Property .EXAMPLE Set-WmiInstance -Namespace 'ROOT' -ClassName 'SCCMZone' -Property $Property -CreateInstance .NOTES This is a module function and can typically be called directly. .LINK https://sccm-zone.com .LINK https://github.com/JhonnyTerminus/SCCM #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false,Position=0)] [string]$Namespace = 'ROOT\cimv2', [Parameter(Mandatory=$false,Position=1)] [string]$ClassName = 'SCCMZone', [Parameter(Mandatory=$false,Position=2)] [string[]]$Key = '', [Parameter(Mandatory=$false,Position=3)] [hashtable]$PropertySearch = '', [Parameter(Mandatory=$true,Position=4)] [hashtable]$Property, [Parameter(Mandatory=$false,Position=5)] [switch]$CreateInstance = $false, [PSCustomObject]$Result = @() ) Try { #move to get instance? # Get Property Names from function input to be used for filtering [string[]]$ClassPropertyNames = $($Property.GetEnumerator().Name) # Get all Instances for the specified Wmi Class, selecting only specified Property Names [PSCustomObject]$ClassInstances = Get-CimInstance -Namespace $Namespace -ClassName $ClassName -ErrorAction 'Continue' | Select-Object $ClassPropertyNames # Convert Property hashtable to PSCustomObject for comparison [PSCustomObject]$InputProperty = [PSCustomObject]$Property # -ErrorAction 'SilentlyContinue' does not seem to work correctly with the Compare-Object commandlet so it needs to be set globaly $ErrorActionPreferenceOriginal = $ErrorActionPreference $ErrorActionPreference = 'SilentlyContinue' # Check if and instance with the same values exists. Since $InputProperty is a dinamically generated object Compare-Object has no hope of working correctly. # Luckily Compare-Object as a -Property parameter which allows us to look at specific parameters. $InstanceSearch = Compare-Object -ReferenceObject $InputProperty -DifferenceObject $ClassInstances -Property $ClassPropertyNames -IncludeEqual -ExcludeDifferent # Setting the ErrorActionPreference back to the previous value $ErrorActionPreference = $ErrorActionPreferenceOriginal # If no matching instance is found, create a new instance, else write error If (-not $InstanceSearch) { $NewInstance = & $NewInstanceScriptBlock } ## Set Connection Props [hashtable]$ConnectionProps = @{ NameSpace = $Namespace; ClassName = $ClassName } ## Test if the Class exists [bool]$ClassTest = Get-WmiClass -Namespace $Namespace -ClassName $ClassName If ($ClassTest) { ## If -PropertySearch parameter was specified use it to get the instances If ($PropertySearch) { $InstanceTest = Get-WmiInstance -Namespace $Namespace -ClassName $ClassName -Property $InputProperty -ErrorAction 'SilentlyContinue' } ## If the -PropertySearch parameter was not specified, use the -Property do get the instances Else { $InstanceTest = Get-WmiInstance -Namespace $Namespace -ClassName $ClassName -Property $Property -ErrorAction 'SilentlyContinue' } ## Count Instances [int16]$InstanceCount = ($InstanceTest | Measure-Object).Count ## Perform actions depending on the $InstanceTest result Switch ($InstanceCount) { # If $InstanceTest is not $null and contains just one instance, Set the new values '1' { $Result = $InstanceTest | Set-CimInstance -Property $Property -ErrorAction 'Stop' } # If $InstanceTest is not $null and contains more than one instance, abort and return error message { $_ -gt '1' } { $Result = 'Set Instance - Failed! More than one instance with the specified values found!' } # If $InstanceTest is $null, the -CreateInstance switch was specified and not matching instance exists, create a new instance with the specified values { $_ -eq '0' -and (-not $InstanceTest) -and $CreateInstance } { # Create a new instance with or without the key parameter If ($Key) { $Result = New-CimInstance -Namespace $Namespace -ClassName $ClassName -Key $Key -Property $Property -ErrorAction 'Stop' } Else { $Result = New-CimInstance -Namespace $Namespace -ClassName $ClassName -Property $Property -ErrorAction 'Stop' } } Default { $Result = 'Unhandled Exception!' } } } Else { $Result = "Set Instance - Failed! $Namespace`:$ClassName does not exist!" } } Catch { $Result = "Set Instance - Failed! `n $_" } Finally { Write-Output -InputObject $Result } } #endregion |