PowerShell DSC – Package ID unknown? Not a problem!

0

With PowerShell Desired State Configuration you’re able to install a package with the Package resource.
However, you’ll need to provide a package ID.
In the past I either created a snapshot of a VM, installed the application and dove in the registry to find the package id.
You could also install ORCA and use that to extract the package ID from the package.

Recently I noticed that PowerShell DSC has a nice little improvement which was introduced somewhere along the line.
When you try and install a package with a faulty package ID in your script, you’ll get an error back from PowerShell stating that
the package ID didn’t match the one found in the package… and stating the package id found inside the package!!!

So, copy-paste the package id from the error message into the DSC configuration and voilá… you’re set to go! :-)

Find parameters named after the plural

0

Over the last few weeks I’ve been working with a vendor to improve the usability of their PowerShell module.

For vendors there is a tool which allows you to automatically create a PowerShell module :-)
This is some very cool stuff, but it takes over the name of properties as they are created in the classes.
So normally a manual review should be desired, at least the first time you generate your module.
They kinda forgot to do that :-)

I also looked at the module to apply some PowerShell Best Practices. For example, parameters should never be named after the plural.

How can you discover those? How can you find parameters named after the plural?

There is no property for that, so you would have to make some educated guesses.
In the English language, most plurals end with an ‘s’. Sometimes even two.
With that in mind, here is some code that allows you to find parameters that probably have been named after the plural :-)

$Modules = Get-Module -ListAvailable
foreach ($Module in $Modules) {
    $Commands = get-command -Module $Module.Name
    foreach ($Command in $Commands) {
        $Parameters = $Command.Parameters
        foreach ($Parameter in $Parameters) {
            $Parameter.Keys | foreach {
                switch ($Parameter.Values) {
                    {$_ -eq 'Verbose'} {break;}
                    {$_ -eq 'Debug'} {break;}
                    {$_ -eq 'ErrorAction'} {break;}
                    {$_ -eq 'WarningAction'} {break;}
                    {$_ -eq 'ErrorVariable'} {break;}
                    {$_ -eq 'WarningVariable'} {break;}
                    {$_ -eq 'OutVariable'} {break;}
                    {$_ -eq 'OutBuffer'} {break;}
                    {$_ -eq 'PipelineVariable'} {break;}
                    default {
                        if (($_ -notlike "*ss") -and ($_ -like "*s")) {        
                            [pscustomobject]@{
                                ModuleName = $Module.Name
                                CommandName = $Command.Name
                                ParameterName = $_
                            }
                        }
                    }
                }
            }
        }
    }
}

Extract features names from DeploymentConfigTemplate xml file

0

I am a lazy person. Trust me on this, it’s true.
So whenever I can find an easy way to accomplish a goal, I do it.
In this post I’ll show you how you can make use of Server Manager, export the configuration to a file and extract the information you need in deployment/configuration scripts from that file.

 

When I need to configure the roles of a server, let’s say ADDS/DNS/DHCP, I have a small and practical tip.
First, I click it. Yes, through a GUI. There are some roles in Windows Server that tend to include a whole bunch of sub-features… but not all of their sub-features.
When you go through the GUI, just before it will actually install, you’ll see the option to export the configuration settings.

This is exported to a XML file.
What I could do is use this file as input for a PowerShell script to install the desired features… but…. There is no such parameter on a cmdlet!

Next to that, I don’t like script dependencies on 2nd files.

So if we get the content of the XML file, we’ll want to filter out the feature names we need.
Getting the content of the XML file is pretty easy:

Get-Content "E:DeploymentConfigTemplate.xml"

But that’s just the content of the file… we want specific values.
When you take a look at the content you’ll see we need the information defined as ‘ClassName’.
Though there are two pieces of information defined as ClassName: The feature name, and ‘MSFT_ServerManagerServerComponentDescriptor’.
So, let’s filter out what we need:

Get-Content "E:DeploymentConfigTemplate.xml" | 
Where-Object {(($_ -notlike "*MSFT_ServerManagerServerComponentDescriptor*") -and ($_ -like "*ClassName*"))}

There are some leading spaces so let’s remove them with the Trim method. However, this method is only available for a string, so we first need to convert it to a string:

Get-Content "E:DeploymentConfigTemplate.xml" | 
Where-Object {(($_ -notlike "*MSFT_ServerManagerServerComponentDescriptor*") -and ($_ -like "*ClassName*"))} | 
foreach {$_.ToString().Trim()}

123
Almost there. We need to remove the crap that’s around the name of the feature:

Get-Content "E:DeploymentConfigTemplate.xml" | 
Where-Object {(($_ -notlike "*MSFT_ServerManagerServerComponentDescriptor*") -and ($_ -like "*ClassName*"))} | 
foreach {$_.ToString().Trim().Replace('<s N="ClassName">ServerComponent_"','').Replace('</S>','')}

One final tricky little thing. There are underscores in the name of the features while Windows works with dashes, not underscores.
So the final code:

Get-Content "E:DeploymentConfigTemplate.xml" | 
Where-Object {(($_ -notlike "*MSFT_ServerManagerServerComponentDescriptor*") -and ($_ -like "*ClassName*"))} | 
foreach {$_.ToString().Trim().Replace('<s N="ClassName">ServerComponent_"','').Replace('</S>','').Replace('_','-')}

Note that there is a more elegant way to accomplish: Use regex.
Since I needed just a quick fix, this was all I needed and had no real need to use regex.

Go to Top