Introduction
In this article, we'll discover some great new features that simplify the life of an administrator or an operator. We'll be shown features like Desired State Configuration. New and extended cmdlets will be demonstrated. Details about PowerShell internals and PowerShell 4.0 internals can be found in my previous article.
Getting Started
Installing PowerShell 4.0 Preview
PowerShell is part of the Windows Management Framework 4.0 (WMF) and can be downloaded here.
The attentive reader might have discovered that there is no download for Windows 8. Why?
Microsoft expects every Windows 8 user to upgrade to Windows 8.1. Windows 8.1 will include WMF 4.0.
Before WMF 4.0 Preview can be installed, .NET Framework 4.5 must be installed! If .NET Framework 4.5 is not installed, amazingly, WMF4 reports that it has already been installed, which of course is nonsense.
Please pay attention to the link above as the Management Framework 4.0 Preview is not compatible with some Microsoft Server applications including all versions of Exchange Server, SharePoint Server, and other applications:
- System Center 2012 Configuration Manager (not including SP1)
- System Center Virtual Machine Manager 2008 R2 (including SP1)
- Microsoft Exchange Server 2013, Microsoft Exchange Server 2010, and Microsoft Exchange Server 2007
- Microsoft SharePoint Server 2013 and Microsoft SharePoint Server 2010
- Windows Small Business Server 2011 and Windows Small Business Server 2008
You really shouldn’t be installing a preview in a production environment anyway, but rather using it locally on your workstation or laptop for testing and familiarization.
PowerShell ISE 4.0
If you use the Microsoft scripting editor, the following might be of great interest for you...
Microsoft has upgraded the integrated scripting environment to support:
- both Windows PowerShell Workflow debugging and remote script debugging.
- IntelliSense for Windows PowerShell Desired State Configuration providers and configurations.
What Has Been Updated?
Besides some bug fixes and the newly added feature DSC, Microsoft has updated the following components:
- Windows PowerShell Web Access
- Windows PowerShell Web Services (Management OData IIS Extension)
- Windows PowerShell Workflow
- Windows PowerShell Integrated Scripting Environment (ISE)
- Windows Remote Management (WinRM)
- Windows Management Instrumentation (WMI)
What's New?
Take notice of the changed date (i.e. 2013) in the copyright string:
Microsoft has updated the version string
s as always:
What's new besides the version information?
Desired State Configuration is a great and the only new feature we'll look at in the next section.
Desired State Configuration
A particularly exciting development is "Desired State Configuration" (DSC) with configurations that work much like PowerShell functions. DSC is a new way of configuring local and remote machines. Instead of writing a lot of script code, you can use the new configuration
keyword which works very similarly to a PowerShell function. These configuration features are called blocks", with which one can either add or remove registry keys, files and folders, local users and groups, as well as Windows features (for servers).
Overview
The actual work is done inside of it, using DSC resources called "group", "service", or "registry", for example. A full list of resources shipped with DSC can be found here.
Each resource is technically represented by a DSC provider you can go and visit:
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSProviders
Note: The DSC providers are nothing other than PowerShell modules under the hood.
The resources that are available are described below:
Archive Resource
The Archive
resource gives you a mechanism to unpack archive (.zip) files at a specific path.
Archive ArchiveExample
{
Ensure ="Present" # You can also set Ensure to "Absent"
Path="C:\Users\Public\Documents\Test.zip"
Destination ="C:\Users\Public\Documents\ExtractionPath"
}
Registry Resource
The Registry
resource gives you a mechanism to manage registry keys and values.
Registry RegistryExample
{
Ensure ="Present" # You can also set Ensure to "Absent"
Key ="HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey"
ValueName="TestValue"
ValueData="TestData"
}
Script Resource
The Script
resource gives you a mechanism to run Windows PowerShell script blocks on target nodes. The TestScript
block runs first. If it returns False
, the SetScript
block will run. The GetScript
block will run when you invoke the Get-DscConfiguration
cmdlet (more on that cmdlet on the flipside of this sheet). GetScript
must return a hash table.
Script ScriptExample
{
SetScript={
$sw=New-ObjectSystem.IO.StreamWriter("C:\TempFolder\TestFile.txt")
$sw.WriteLine("Some sample string")
$sw.Close()
}
TestScript ={Test-Path"C:\TempFolder\TestFile.txt"}
GetScript={ <# This must return a hash table #>}
}
Package Resource
The Package
resource gives you a mechanism to install and manage packages, such as MSI and setup.exe packages, on a target node.
Package PackageExample
{
Ensure ="Present"# You can also set Ensure to "Absent"
Path ="$Env:SystemDrive\TestFolder\TestProject.msi"
Name ="TestPackage"
ProductId ="663A8209-89E0-4C48-898B-53D73CA2C14B"
}
Environment Resource
The Environment
resource gives you a mechanism to manage system environment variables.
Environment EnvironmentExample
{
Ensure ="Present" # You can also set Ensure to "Absent"
Name ="TestEnvironmentVariable"
Value ="TestValue"
}
Group Resource
The Group
resource gives you a mechanism to manage local groups on the target node.
Group GroupExample
{
# This will remove TestGroup,if present
# To create a new group, set Ensure to "Present"
Ensure ="Absent"
GroupName="TestGroup"
}
User Resource
The User
resource gives you a mechanism to manage local user accounts on the target node.
User UserExample
{
Ensure ="Present"# To delete a user account, set Ensure to "Absent"
UserName="SomeName"
Password =$passwordCred# This needs to be a credential object
Requires ="[Group]GroupExample"# Configures GroupExamplefirst
}
Service Resource
The Service
resource gives you a mechanism to manage services on the target node.
Service ServiceExample
{
Name ="TermService"
StartupType="Manual"
}
Putting It All Together
Creating a Configuration File
Please find below sample configuration file.
Configuration MyTestConfig
{
param ($MachineName)
Node $MachineName
{
Group TestGroup
{
Ensure ="Present"
GroupName="TestGroup"
}
Service WinUpdate
{
Name ="wuauserv"
StartupType="Automatic"
}
Script ScriptExample
{
SetScript={
$sw=New-Object System.IO.StreamWriter("$env:temp\TestFile.txt")
$sw.WriteLine("Some sample string")
$sw.Close()
}
TestScript ={Test-Path "C:\Temp\TestFile.txt"}
GetScript={ <# This must return a hash table #> }
}
Registry RegistryExample
{
Ensure ="Present" # You can also set Ensure to "Absent"
Key ="HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey"
ValueName="TestValue"
ValueData="TestData"
}
Environment EnvironmentExample
{
Ensure ="Present" # You can also set Ensure to "Absent"
Name ="TestEnvironmentVariable"
Value ="TestValue"
}
}
}
Turning a Configuration into a MOF File
The actual configuration is not done by your script. Instead, your script takes the configuration data (your parameters) and turns it into a MOF file. Here are two lines of code that illustrate how you’d turn the above configuration into a MOF file:
$null = md C:\TEMP\dscconfig -ErrorAction SilentlyContinue
MyTestConfig -MachineName $env:COMPUTERNAME -OutputPath C:\TEMP\dscconfig
The resulting configuration file will be stored as {target node name}.MOF, if you specify multiple machine names multiple MOF-Files will be created - each MOF-File represents one target node. Your MOF-File will be similar to the one listed below (in my case, the target node name is 'DEVENV
'):
instance of MSFT_GroupResource as $MSFT_GroupResource1ref
{
ResourceID = "[Group]TestGroup";
Ensure = "Present";
GroupName = "TestGroup";
SourceInfo = "::6::9::Group";
ModuleName = "MSFT_GroupResource";
ModuleVersion = "1.0";
Requires = {
};
};
instance of MSFT_ServiceResource as $MSFT_ServiceResource1ref
{
ResourceID = "[Service]WinUpdate";
SourceInfo = "::11::9::Service";
Name = "wuauserv";
StartupType = "Automatic";
ModuleName = "MSFT_ServiceResource";
ModuleVersion = "1.0";
Requires = {
};
};
instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
{
ResourceID = "[Script]ScriptExample";
GetScript = " <# This must return a hash table #> ";
TestScript = "Test-Path \"C:\\Temp\\TestFile.txt\"";
SourceInfo = "::16::9::Script";
SetScript = "\n $sw=New-Object System.IO.StreamWriter(
\"$env:temp\\TestFile.txt\")\n $sw.WriteLine(
\"Some sample string\")\n $sw.Close()
\n ";
ModuleName = "MSFT_ScriptResource";
ModuleVersion = "1.0";
Requires = {
};
};
instance of MSFT_RegistryResource as $MSFT_RegistryResource1ref
{
ResourceID = "[Registry]RegistryExample";
ValueName = "TestValue";
Key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\ExampleKey";
Ensure = "Present";
SourceInfo = "::26::10::Registry";
ModuleName = "MSFT_RegistryResource";
ValueData = {
"TestData"
};
ModuleVersion = "1.0";
Requires = {
};
};
instance of MSFT_EnvironmentResource as $MSFT_EnvironmentResource1ref
{
ResourceID = "[Environment]EnvironmentExample";
Ensure = "Present";
Value = "TestValue";
SourceInfo = "::33::10::Environment";
Name = "TestEnvironmentVariable";
ModuleName = "MSFT_EnvironmentResource";
ModuleVersion = "1.0";
Requires = {
};
};
instance of OMI_ConfigurationDocument
{
Version="1.0.0";
Author="Administrator";
GenerationDate="07/29/2013 09:07:05";
GenerationHost="DEVENV";
};
Applying a MOF File
Calling Start-DscConfiguration
will invoke the DSC engine on the target machine(s). The actual work is done by the DSC resource (i.e., the PowerShell module).
Parameters
Path represents the target directory where your MOF-files are located.
Wait causes the execution of the DSC resources to run in background, i.e., an interactive process.
Start-DscConfiguration -Wait -Path C:\TEMP\dscconfig
Result
Every step configured in our PowerShell test configuration file has been executed against the target machine(s). For example, the registry key including value and data has been created as we desired:
Links