Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!
PowerShell

Creating DSC Resource Snippets for the PowerShell ISE

Without a doubt creating configurations for Desired State Configuration (DSC) in PowerShell 4.0 is one of the hottest topics in the PowerShell world these days. But as is often the case with new technologies, discovering what to use can be a challenge. Fortunately for PowerShell and DSC this does not have to be difficult task.

Using the Get-DSCResource cmdlet

In a DSC configuration you need to define resources for the managed nodes. You can use the Get-DSCResource cmdlet to discover resources installed locally. Even though you will be creating configurations for servers, you will most likely be using the PowerShell ISE on a Windows 8.1client. Given that you will most likely have the same DSC resource modules installed locally.

One of the reasons for this is so that you can discover the resource syntax. The Get-DSCResource cmdlet can either display information about a resource or provide its syntax. Let’s say you are creating a configuration that will use the xSMBShare resource. You can see the syntax like this:

Get-DscResource xsmbshare -Syntax

Creating DSC Resource Snippets for the PowerShell ISE

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

You can then copy and paste this into the ISE. Or copy it directly to the clipboard.

Get-DscResource xsmbshare –Syntax | clip

Another option is to use a function in the ISE to get the syntax and paste it into the current document.

Function Insert-DSCSyntax {
Param([string]$Name)
Try {
[string]$syntax = Get-DscResource -Name $Name -Syntax
#insert into current document at current location
$psise.CurrentFile.Editor.InsertText($syntax)
}
Catch {
throw
}
}

Run the function specifying a resource name and the syntax will be pasted into the current file. Or how about this? Use Out-GridView as an object picker for the resources you want to use?

Get-DscResource | Select Name,Module | 
Out-GridView -title "Select some resources" -OutputMode Multiple |
Foreach {
 Insert-DSCSyntax $_.Name
}

When I click OK the syntax for the selected resources will be inserted into my current file. This will run much faster in PowerShell 5.0 but gets the job done. All I need to do is edit each entry. But I have an approach I like even better. Why not turn each resource syntax into an ISE snippet?

With an ISE Snippet you press Ctrl+J, find the snippet, press Enter and the text is inserted into the current file. My initial thought was to use the Syntax string with the New-ISESnippet cmdlet. But then I’d have to mess around with parsing the output to find something to use for a title. So instead, I came up with this function.

#requires -version 4.0

Function New-DSCResourceSnippet {

<#
.Synopsis
Create ISE snippets for DSC Resources
.Description
This command will convert the syntax for a DSC resource into an ISE snippet. Snippets will be created in the default location. Snippet names will take the name "DSC <resource name>". The snippet description uses the format "<Resource Name> resource from module <module name> <vendor>". You will end up with a description like this:

xWinEventLog resource from module xWinEventLog Microsoft Corporation

You must run this command in the PowerShell ISE.

.Example
PS C:\> New-DSCResourceSnippet -name xsmbshare -author "Jeff Hicks" -passthru


    Directory: C:\Users\Jeff\documents\WindowsPowerShell\Snippets


Mode                LastWriteTime     Length Name                                                              
----                -------------     ------ ----                                                              
-a---        10/20/2014   8:48 AM       1157 DSC xSmbShare Resource.snippets.ps1xml            

Create a snippet from a single resource.
.Example
PS C:\> Get-DSCResource | New-DSCResourceSnippet

This command will create snippets for every installed DSC resource. Existing snippet files will be overwritten.
.Notes
Last Updated: October 20, 2014
Version     : 1.0

Learn more about PowerShell:
http://jdhitsolutions.com/blog/essential-powershell-resources/

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

.Link
Get-DSCResource
New-ISESnippet
#>

[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="Name")]
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter the name of a DSC resource",
ParameterSetName="Name")]
[ValidateNotNullorEmpty()]
[string[]]$Name,
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter the name of a DSC resource",
ValueFromPipeline=$True,ParameterSetName="Resource")]
[ValidateNotNullorEmpty()]
[Microsoft.PowerShell.DesiredStateConfiguration.DscResourceInfo[]] $DSCResource,
[ValidateNotNullorEmpty()]
[string]$Author = $env:username,
[Switch]$Passthru
)

Begin {
    Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"  
} #begin

Process {

if ($PSCmdlet.ParameterSetName -eq 'Name') {
    #get the resource from the name
    Try {
        Write-Verbose "Getting DSC Resource $Name"
        $DSCResource = Get-DscResource -Name $Name -ErrorAction Stop
    }
    Catch {
        Throw
    }
}

foreach ($resource in $DSCResource) {

#create the entry based on resource properties
[string[]]$entry = "`n$($resource.name) <ResourceID> {`n"

    Write-Verbose "Creating resource entry for $($resource.name)"
    $entry+= "`t#from module $($resource.module.name)"
    $entry+=  foreach ($item in $resource.Properties) {
     if ($item.IsMandatory) {
       $resourcename="`t*$($item.name)"
     }
     else {
     $resourcename = "`t$($item.name)"
     }

     if ($item.PropertyType -eq '[bool]') {
       $possibleValues = "`$True | `$False"
     }
    elseif ($item.values) {
      $possibleValues = "'$($item.Values -join "' | '")'"
     }
    else {
      $possibleValues=$item.PropertyType
    } 
    "$resourcename = $($possibleValues)"

    } #foreach

$entry+="`n} #end $($resource.name) resource`n`n"

$title = "DSC $($resource.name) Resource"
$description = "$($resource.name) resource from module $($resource.module) $($resource.CompanyName)"

Write-Verbose "Creating snippet $title"
Write-Verbose $description
Write-Verbose ($entry | out-string)

$paramHash = @{
 Title = $Title
 Description = $description
 Text = ($Entry | Out-String)
 Author = $Author
 Force = $True
 ErrorAction = "Stop"
}

Write-Verbose ($paramHash | out-string)
if ($PSCmdlet.ShouldProcess($Resource.name)) {
    
    Try {
      Write-Debug "Creating snippet file"
      New-IseSnippet @paramHash
    
        if ($Passthru) {
            #build the path
            $snippath = join-path -path "$env:Userprofile\documents\WindowsPowerShell\Snippets" -ChildPath "$title.snippets.ps1xml"
            Get-Item -path $snippath
        }
    } 
    Catch {
        Throw
    }

} #if shouldprocess
} #foreach resource

} #process

End {
    #import the new snippets into the current session. They will 
    #automatically be loaded next time.
    Write-Verbose "Importing new snippets"
    Import-IseSnippet -Path "$env:Userprofile\documents\WindowsPowerShell\Snippets"
    Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
} #end


} #end function

This is something you really only need to run once and it must be done from the PowerShell ISE. Or you can re-run it if you install new or updated resource modules. The function takes the name of a resource and constructs the syntax from the resource properties. Mandatory properties will be indicated with a *. The function will create a snippet file in the default user location using the resource name as the title. The module and vendor name will be included in the description. You can use it to create a single snippet.

New-DSCResourceSnippet -name xsmbshare -author "Jeff Hicks" –passthru

Or create snippets for everything.

Get-DSCResource | New-DSCResourceSnippet

The function will automatically import them into your current ISE session so you can use them immediately. The next time you start the ISE they should automatically be available. Once run, you can easily insert new resources.

All of the snippets will start with DSC. Once inserted, edit as necessary. With this, creating configurations for DSC is much, much easier and faster. The function has full help and examples. I definitely hope you’ll try this out and let me know what you think.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.

RSVP Now

Sponsored By