Discovering namespaces part 2

I recently showed how to use Get-CimInstance to discover the namespaces present in a particular CIM namespace. I’m going to try to use CIM instaed of WMI but expect the old terminology to creep in occasionally.
The function I showed last time will only find the first level of namespaces in a namespace – what if those namespaces contain namespaces.
This is where you get to meet the concept of recursion. In this case all it means is that we’re going to call our function from within the function. Its easier to show with code.
function get-cimnamespace {
param (
[string]$namespace = ‘root/cimv2’,
[switch]$nobase
)
if (-not $nobase)
{
New-Object -TypeName psobject -Property @{
Name = $namespace
}
}
Get-CimInstance -ClassName __NameSpace -Namespace $namespace |
foreach {
$ns = New-Object -TypeName psobject -Property @{
Name = “$($psitem.CimSystemProperties.NameSpace)/$($psitem.Name)”
}
Write-Output $ns
get-cimnamespace -namespace $ns.Name -nobase
}
}
The function has 2 parameters – the startign namespace parameter and a switch parameter. The switch controls if the namespace used as a parameter is output.
Get-CimInstance is used to find each instance of the __Namespace class. Foreach instance the namespace name is output and then used to call get-cimnamespace with the new namespace as a paramter. Its already been output so the –nobase switch is used to prevent duplicate output. And that’s recursion.
On my test machine I get this
£> get-cimnamespace
Name
—-
root/cimv2
ROOT/cimv2/mdm
ROOT/cimv2/mdm/MS_40c
ROOT/cimv2/mdm/MS_809
ROOT/cimv2/mdm/MS_413
ROOT/cimv2/mdm/MS_409
ROOT/cimv2/mdm/MS_407
ROOT/cimv2/ms_40c
ROOT/cimv2/Security
ROOT/cimv2/Security/MicrosoftTpm
ROOT/cimv2/Security/MicrosoftVolumeEncryption
ROOT/cimv2/ms_809
ROOT/cimv2/power
ROOT/cimv2/power/MS_40c
ROOT/cimv2/power/ms_809
ROOT/cimv2/power/MS_413
ROOT/cimv2/power/ms_409
ROOT/cimv2/power/MS_407
ROOT/cimv2/ms_413
ROOT/cimv2/ms_409
ROOT/cimv2/TerminalServices
ROOT/cimv2/TerminalServices/ms_40c
ROOT/cimv2/TerminalServices/ms_809
ROOT/cimv2/TerminalServices/ms_413
ROOT/cimv2/TerminalServices/ms_407
ROOT/cimv2/ms_407
ROOT/cimv2/Applications
ROOT/cimv2/Applications/WindowsParentalControls
ROOT/cimv2/Applications/WindowsParentalControls/Secured
ROOT/cimv2/Applications/Games
ROOT/cimv2/Applications/Games/ms_40c
ROOT/cimv2/Applications/Games/ms_809
ROOT/cimv2/Applications/Games/ms_413
ROOT/cimv2/Applications/Games/ms_409
ROOT/cimv2/Applications/Games/ms_407
I’m loading the function as part of a CimInvetsigation module which now has 2 cmdlets:
Get-CimMethod
Get-CimNamespace
Windows Server 2012 R2 Update

The Windows Server 2012 R2 Update (and the corresponding Windows 8.1 Update) are available to MSDN/TechNet subscribers. General availability follows on 8 April (patch Tuesday)
Windows Management Framework V5

The Windows Server blog has an announcement, and download link, for WMF v5.
The headline items are OneGet and cmdlets for managing network switches that conform to the Certified for Windows Network program.
OneGet is a way to discover, and install, software packages. In this release you can search for and install software from Chocolatey repositories.
There are also some fixes and enhancements to DSC to improve performance.
CIM snippets–working with file system

The latest instalment from the WMI team on using PowerShell and the CIM cmdlets is available – http://blogs.msdn.com/b/wmi/archive/2014/03/28/performing-management-tasks-using-cim-cmdlets-4-files-and-folders.aspx
This time round the examples are to do with working with the file system – files, folders and shares.
If you’ve worked with WMI you’ll be aware of that very often you get 2 classes one with a prefix of CIM (base class from DMTF definition) and one with Win32 prefix which is the Microsoft implementation. They 2 classes are often identical though the Win32 class may have additions.
The WMI class for working with files is different – it only has a CIM version CIM_DataFile.
The first example in the post is about renaming a file. A much simpler coding of the task would be:
Get-CimInstance -ClassName CIM_Datafile -Filter “Name = ‘C:\\Test\\Names.txt'” | Invoke-CimMethod -MethodName Rename -Arguments @{FileName = ‘C:\\Test\\OldNames.txt’}
A couple of points to note:
– when dealing with file paths all \ characters must be doubled. This is because \ is a WMI escape character so you need to escape it to use it literally.
– Invoke-CimMethod uses a hash table for the method arguments with the argument name as the key – this takes away any of the argument order issues you see with Invoke-WmiMethod)
One perennial problem for administrators is users putting their own files on the organization’s file servers. Want to know if there any files of a specific type in a folder?
Get-CimInstance -ClassName CIM_Datafile -Filter “Extension = ‘txt’ AND Path = ‘\\test\\'”
If you leave the path out of the filter then all files on the drive will be searched – could take a while. Being specific in your filter will save you a lot of time.
Want to find all the mp3 files on a drive?
Get-CimInstance -ClassName CIM_Datafile -Filter “Extension = ‘mp3′”
You can’t create files and folders with CIM (or WMI) but you can create shares
$margs = @{
Path = ‘C:\Test’
Name = ‘Test2April’
Description = ‘TestShare’
Type = [uint32]0
}
Invoke-CimMethod -ClassName Win32_Share -MethodName Create -Arguments $margs
Create the hash table of arguments separately – its easier to read. Bizarrely this time you don’t need to escape the \ in the path
You can see the shares on a system like this:
Get-CimInstance -ClassName Win32_Share
CIM may not be you first port of call when working with the file system but it can be useful – especially on remote systems.
You can find out much more about using CIM to work with the file system in chapetr 8 of PowerShell and WMI – www.manning.com/siddaway2
MVP award renewed

Received an email this afternoon renewing my PowerShell MVP award for another year. This is a great honour and I’d like to thank you for helping to make this possible by reading my blog posts.
DSC resource kit wave 3

Desired State Configuration (DSC) is the new server configuration and compliance mechanism that ships with PowerShell 4.0 and Windows Server 2012 R2.
Resources are the way you perform configuration. Now you have more options with the release of wave 3 of the DSC resource kit.
Details from http://blogs.msdn.com/b/powershell/archive/2014/03/28/dsc-resource-kit-wave-3.aspx
Last few days to register

Reaching the end of March there’s not much time left to register for the PowerShell Summit NA 2014 –
as its coming up fast.
See you there.
Discovering namespaces

Next point on the journey of discovery through CIM is finding the namespaces installed on a machine. I showed how to do this using Get-WmiObject in PowerShell and WMI but this time round decided to come up to date and use Get-CimInstance
function get-cimnamespace {
param (
[string]$namespace = ‘root/cimv2′
)
Get-CimInstance -ClassName __NameSpace -Namespace $namespace |
select @{N=’Name’; E={“$($_.CimSystemProperties.NameSpace)/$($_.Name)”}}
}
This simply searches for instances of the __NameSpace class in a given starting name space. Default is root/cimv2. By using select-object to create a calculated field I can append the name of the namespace to the current namespace to get the full path.
Next time I’ll show how to use recursion to dig through the namespaces we’re discovering to find any namespaces they contain.
Improving CIM/WMI method discovery

I recently showed how to create a function that could be used to simplify the use of Get-CimClass.
In this version I’ve added some features:
– parameter validation
– namespace
– try-catch round getting the class information.
This turns the code into:
function Get-CimMethod {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[Alias(“Class”)]
[ValidateNotNullOrEmpty()]
[string]$classname,
[ValidateNotNullOrEmpty()]
[string]$namespace = ‘root/cimv2’,
[Alias(“Name”)]
[ValidateNotNullOrEmpty()]
[string]$methodname
)
try
{
$class = Get-CimClass -Namespace $namespace -ClassName $classname -ErrorAction Stop
}
catch
{
Throw “Class: $classname NOT FOUND”
}
if ($methodname)
{
$class.CimClassMethods[$methodname].Parameters
}
else
{
$class.CimClassMethods
}
}
The module and function can be used like this:
Import-Module CimInvestigation -Force
Get-Command -Module CimInvestigation
Get-CimMethod -classname Win32_Process
Get-CimMethod -classname Win32_Process -methodname Create
Get-CimMethod -classname Win32_Process -methodname Create -namespace root/cimv2
Deal of the Day–26 March

Tomorrow – 26 March – several PowerShell books will feature in Manning’s Deal of the Day:
PowerShell in Depth 2E
PowerShell and WMI
PowerShell Deep Dives
All highly recommended and full of PowerShell goodness