I’ve amended the new-cdxml function created earlier in the series:
function new-cdxml {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$class,
[Parameter(Mandatory=$true)]
[string]$noun,
[string]$namespace = ‘ROOT\cimv2’,
[string]$path = "C:\Scripts\Modules\Hardware"
)
$code = @"
<?xml version=’1.0′ encoding=’utf-8′?>
<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>
<Class ClassName=’$namespace\$class’>
<Version>1.0</Version>
<DefaultNoun>$noun</DefaultNoun>
<InstanceCmdlets>
<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>
</GetCmdletParameters>
</InstanceCmdlets>
</Class>
</PowerShellMetadata>
"@
$file = Join-Path -Path $path -ChildPath "$class.cdxml"
Write-Verbose -Message $file
Set-Content -Path $file -Value $code
}
The change is making the class and noun parameters mandatory. In PowerShell 3 & 4 you can simplify the syntax slightly:
param (
[Parameter(Mandatory)]
[string]$class,
[Parameter(Mandatory)]
[string]$noun,
[string]$namespace = ‘ROOT\cimv2’,
[string]$path = "C:\Scripts\Modules\Hardware"
)
I prefer to use the PowerShell 2.0 syntax and actually state that Mandatory=$true. This is for 2 reasons. Firstly, its what I’m used to and it works – I haven’t got round to changing my default templates. Secondly, I prefer to use this syntax because its immediately apparent to me that the parameter is Mandatory.
This time I’ve used the Win32_NetworkAdapterConfiguration class because it enables me to introduce the use of search (filter) parameters in CDXML cmdlets; it has a number of very useful methods and it enables me to introduce the use of format files.
Using new-cdxml you can create the basic module
<?xml version=’1.0′ encoding=’utf-8′?>
<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>
<Class ClassName=’ROOT\cimv2\Win32_NetworkAdapterConfiguration’>
<Version>1.0</Version>
<DefaultNoun>NetworkAdapterConfiguration</DefaultNoun>
<InstanceCmdlets>
<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>
</GetCmdletParameters>
</InstanceCmdlets>
</Class>
</PowerShellMetadata>
To add this into the module manifest amend these two lines as shown:
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = @(‘Win32_BIOS.cdxml’,
‘Win32_ComputerSystem.cdxml’,
‘Win32_DiskDrive.cdxml’,
‘Win32_NetworkAdapterConfiguration.cdxml’
)
# Functions to export from this module
FunctionsToExport = @(‘Get-Bios’,
‘Get-ComputerSystem’,
‘Get-PhysicalDisk’,
‘Get-NetworkAdapterConfiguration’
)
You now have a hardware module consisting of:
£> Get-Command -Module Hardware
CommandType Name
———– —-
Function Get-Bios
Function Get-ComputerSystem
Function Get-NetworkAdapterConfiguration
Function Get-PhysicalDisk
The output from Get-NetworkAdapterConfiguration on my Windows 8.1 virtual machine looks like this:
ServiceName DHCPEnabled Index Description
———– ———– —– ———–
netvsc False 0 Microsoft Hyper-V Network Adapter
kdnic True 1 Microsoft Kernel Debug Network Adapter
tunnel False 3 Microsoft ISATAP Adapter
netvsc False 4 Microsoft Hyper-V Network Adapter #2
tunnel False 5 Microsoft ISATAP Adapter
Now this is the same display that Get-CimInstance produces and for my purposes it doesn’t work. I need to create a format file to produce the display I need. I also want to be able to filter on various criteria including DHCPEnabled, IPEnabled, InterfaceIndex, Index and Description. I also want to be able to search on any of these individually or in any logical combination