none
Writing a custom WMI class RRS feed

  • Question

  • Hello PS community,

    Looking for some assistance with writing a custom WMI class using PowerShell. This is unfamiliar territory for me, so most of what I have is based on online references. I'm still going through the different methods for accomplishing this task.

    After executing my code I run Get-WmiObject -Class CORP_Jobs. All I see in the class is data for the last line of the CSV file. I'm fairly certain it is due to my foreach loop. Any thoughts?

    I have a CSV file containing the below contents. My goal is to create a class under root\cimv2 called "CORP_Jobs" with an instance for ID, Name, and State.

    ID	Name	State
    001A	Job1	Complete
    001B	Job2	Suspended
    001C	Job3	Error

    This is the code I have currently:

    Function New-WMI-Class {
    
        $newClass = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
    
        $newClass["__CLASS"] = "CORP_Jobs";
    
        $newClass.Properties.Add("ID", [System.Management.CimType]::String, $false)
        $newClass.Properties["ID"].Qualifiers.Add("key", $true)
        $newClass.Properties["ID"].Qualifiers.Add("read", $true)
    
        $newClass.Properties.Add("Name", [System.Management.CimType]::String, $false)
        $newClass.Properties["Name"].Qualifiers.Add("read", $true)
    
        $newClass.Properties.Add("State", [System.Management.CimType]::String, $false)
        $newClass.Properties["State"].Qualifiers.Add("read", $true)
    
        $newClass.Put()
    
    }
    
    $CorpJobs = Import-CSV -Path "C:\Temp\import.csv"
    
    if ($CorpJobs) {
    
        New-WMI-Class
    
        foreach ($CorpJob in $CorpJobs) {
    
            Set-WmiInstance -Path \\.\root\cimv2:CORP_Jobs -Arguments @{
    
                ID = $($CorpJob.ID); `
                Name = $($CorpJob.Name); `
                State = $($CorpJob.State)
    
            }
    
        }
    
    }



    Monday, July 3, 2017 11:07 PM

Answers

  • It took me a bit to remember how to do this:  "ID" and "Name" are reserved.  ID generates a GUID when defined. "Name" is the name of the class.

    Function New-WMI-Class {
    	$newClass = New-Object System.Management.ManagementClass('root\cimv2')
    	
    	$newClass['__CLASS'] = 'CORP_Jobs'
    	
    	$newClass.Properties.Add('myID', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myID'].Qualifiers.Add('key', $true)
    	$newClass.Properties['myID'].Qualifiers.Add('read', $true)
    	
    	$newClass.Properties.Add('myName', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myName'].Qualifiers.Add('read', $true)
    	
    	$newClass.Properties.Add('myState', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myState'].Qualifiers.Add('read', $true)
    	
    	$newClass.Put()
    }
    
    
    New-WMI-Class
    if($CorpJobs = Import-CSV C:\Temp\import.csv){
    	foreach ($CorpJob in $CorpJobs) {
    		$proplist = @{		
    			myID    = $CorpJob.ID
    			myName  = $CorpJob.Name
    			myState = $CorpJob.State
    		}
    		New-CimInstance -ClassName CORP_Jobs -Namespace root\Cimv2 -Property $proplist
    	}
    }

    Test this.  When you understand how it works then you can change the property names as needed.

    To remove the test class:

    $cls = [System.Management.ManagementClass]::new('\\.\root\cimv2:CORP_Jobs')
    $cls.Delete()


    \_(ツ)_/



    Monday, July 3, 2017 11:53 PM
    Moderator

All replies

  • More like this:

    New-WMI-Class
    if($CorpJobs = Import-CSV C:\Temp\import.csv){
    	foreach ($CorpJob in $CorpJobs) {
    		$arglist = @{		
    			ID    = $CorpJob.ID
    			Name  = $CorpJob.Name
    			State = $CorpJob.State
    		}
    		Set-WmiInstance -CORP_Jobs -Arguments $arglist
    	}
    }

    You only want one class definition but multiple instances of the class.


    \_(ツ)_/


    Monday, July 3, 2017 11:22 PM
    Moderator
  • It took me a bit to remember how to do this:  "ID" and "Name" are reserved.  ID generates a GUID when defined. "Name" is the name of the class.

    Function New-WMI-Class {
    	$newClass = New-Object System.Management.ManagementClass('root\cimv2')
    	
    	$newClass['__CLASS'] = 'CORP_Jobs'
    	
    	$newClass.Properties.Add('myID', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myID'].Qualifiers.Add('key', $true)
    	$newClass.Properties['myID'].Qualifiers.Add('read', $true)
    	
    	$newClass.Properties.Add('myName', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myName'].Qualifiers.Add('read', $true)
    	
    	$newClass.Properties.Add('myState', [System.Management.CimType]::String, $false)
    	$newClass.Properties['myState'].Qualifiers.Add('read', $true)
    	
    	$newClass.Put()
    }
    
    
    New-WMI-Class
    if($CorpJobs = Import-CSV C:\Temp\import.csv){
    	foreach ($CorpJob in $CorpJobs) {
    		$proplist = @{		
    			myID    = $CorpJob.ID
    			myName  = $CorpJob.Name
    			myState = $CorpJob.State
    		}
    		New-CimInstance -ClassName CORP_Jobs -Namespace root\Cimv2 -Property $proplist
    	}
    }

    Test this.  When you understand how it works then you can change the property names as needed.

    To remove the test class:

    $cls = [System.Management.ManagementClass]::new('\\.\root\cimv2:CORP_Jobs')
    $cls.Delete()


    \_(ツ)_/



    Monday, July 3, 2017 11:53 PM
    Moderator
  • Thank you JRV - I'll try this out now.

    2 questions:

    1. My plan was to remove the class entirely if it already exists, using Get-WmiObject -Class CORP_Jobs | Remove-WmiObject. Is this a good practice?
    2. I see you are using New-CimInstance to assign the values. Is this preferred over Set-WmiInstance?
    Tuesday, July 4, 2017 12:15 AM