CDXML

Its been stated many times that over 60% of the modules in PowerShell 3 & 4 are created using CDXML – objects-over-cmdlets.

This involves taking a WMI class and wrapping it in XML to create a PowerShell module. At this time many admins are running for the door but it really isn’t that difficult.

Most admins will have used the Win32_Bios class

£> Get-CimInstance -ClassName Win32_Bios


SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : BIOS Date: 05/23/12 17:15:53  Ver: 09.00.06
SerialNumber      : 5518-5018-0990-2526-2313-2106-44
Version           : VRTUAL – 5001223

 

To create a CDXML file type this in ISE:

<?xml version="1.0" encoding="utf-8"?>
<PowerShellMetadata xmlns="http://schemas.microsoft.com/cmdlets-over-objects/2009/11">
  <Class ClassName="ROOT\cimv2\Win32_BIOS">
    <Version>1.0</Version>
    <DefaultNoun>Bios</DefaultNoun>

    <InstanceCmdlets>
      <GetCmdletParameters DefaultCmdletParameterSet="DefaultSet">
             
      </GetCmdletParameters>
    </InstanceCmdlets> 
  </Class>
 
</PowerShellMetadata>

 

Everything is boiler plate except two lines:

<Class ClassName="ROOT\cimv2\Win32_BIOS">
which shows the namespace and the class you are using

 

   <DefaultNoun>Bios</DefaultNoun>

which sets the NOUN of the PowerShell cmdlet you are producing. The verb is automatically set to GET.

I keep all my scripts in a folder called c:\scripts – this has subfolders by category. I also amend my module path in my PowerShell profile

$env:PSModulePath = "C:\Scripts\Modules;" + $env:PSModulePath

to add the \scripts\modules folder. This folder has all of the module I develop to keep them separate from the Microsoft modules.

 

I’m creating a module called Hardware that will contain a suite of CDXML files for accessing WMI classes related to hardware.

I saved the XML above to C:\Scripts\Modules\Hardware\Win32_BIOS.cdxml

For testing I change directory the C:\Scripts\Modules\Hardware folder and I can test my new module.

£> Import-Module .\Win32_BIOS.cdxml
£> Get-Command -Module Win32_BIOS

CommandType     Name                   ModuleName
-----------     ----                   ----------
Function        Get-Bios               Win32_BIOS

 

Running Get-Bios produces:

£> get-bios


SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : BIOS Date: 05/23/12 17:15:53  Ver: 09.00.06
SerialNumber      : 5518-5018-0990-2526-2313-2106-44
Version           : VRTUAL – 5001223

 

Exactly the same as using Get-CimInstance.

You also get a set of free functionality (meaning you don’t have to do anything)

£> Get-Command Get-Bios -Syntax

Get-Bios [-CimSession <CimSession[]>] [-ThrottleLimit <int>] [-AsJob] [<CommonParameters>]

£> $sess = New-CimSession -ComputerName server02
£> Get-Bios -CimSession $sess


SMBIOSBIOSVersion : 6NET61WW (1.24 )
Manufacturer      : LENOVO
Name              : Ver 1.00PARTTBLX
SerialNumber      : R81BG3K
Version           : LENOVO - 1240
PSComputerName    : server02

 

The properties displayed are controlled by the PowerShell formatting system as with most WMI classes. You can display all data:

Get-Bios | Format-List *

 

Next time we’ll create a module manifest file to enable module auto-loading

Leave a Reply