{"id":6201,"date":"2015-05-12T00:01:00","date_gmt":"2015-05-12T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/05\/12\/write-targetresource-functions-for-powershell-dsc\/"},"modified":"2019-02-18T10:29:37","modified_gmt":"2019-02-18T17:29:37","slug":"write-targetresource-functions-for-powershell-dsc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/write-targetresource-functions-for-powershell-dsc\/","title":{"rendered":"Write TargetResource Functions for PowerShell DSC"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Guest blogger and Microsoft PFE, Jason Walker, talks about writing <\/span><b style=\"font-size:12px\">Get<\/b><span style=\"font-size:12px\">, <\/span><b style=\"font-size:12px\">Set<\/b><span style=\"font-size:12px\">, and <\/span><b style=\"font-size:12px\">Test TargetResource<\/b><span style=\"font-size:12px\"> functions for DSC.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Microsoft PFE and Honorary Scripting Guy, <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/tag\/jason-walker\/\" target=\"_blank\">Jason Walker<\/a>, is back with us today for Part 2 of his two-part series.<\/p>\n<p>Yesterday in <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/anatomy-of-a-powershell-dsc-resource\/\" target=\"_blank\">Anatomy of a PowerShell DSC Resource<\/a>, I gave an overview of the anatomy of a DSC resource and explained how to use the <b>xDscResourceDesigner<\/b> module to lay down the foundation of a DSC resource. Today I will explain what is involved in writing your <b>Get<\/b>, <b>Set<\/b>, and <b>Test TargetResource<\/b> functions. I&rsquo;m going to start with the <b>Test-TargetResource<\/b> function because, in most cases, it will take the longest to write.<\/p>\n<p>The <b>Test-TargetResource<\/b> function needs to be able to compare every parameter that is defined in the schema.mof file to what is the reality on the server. If the server matches the configuration script, it returns <b>$true<\/b>, and if the server does not match, it returns <b>$false<\/b>. Here is how this looks in the example:<\/p>\n<p><span style=\"font-size:12px\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/heg-5-12-15-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/heg-5-12-15-1.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><br \/><\/span><\/p>\n<p><span style=\"font-size:12px\">To summarize the code in the example, the <\/span><b style=\"font-size:12px\">Test-TargetResource<\/b><span style=\"font-size:12px\"> function will get the current configuration and store the results in <\/span><b style=\"font-size:12px\">$ItemResult<\/b><span style=\"font-size:12px\">. It then compares <\/span><b style=\"font-size:12px\">$ItemResult<\/b><span style=\"font-size:12px\"> to the configuration script. To break this down even further, if <\/span><b style=\"font-size:12px\">$Ensure<\/b><span style=\"font-size:12px\"> is present, and <\/span><b style=\"font-size:12px\">$ItemResult<\/b><span style=\"font-size:12px\"> exists without an error, the node must be in a desired state, so the script will return TRUE. If not, it will return FALSE, meaning the node is not in a desired state. After that, a check for the opposite condition is performed.<\/span><\/p>\n<p>You will also notice the use of <b>Write-Verbose<\/b>. This is not only beneficial when manually running the configuration to monitor progress&mdash;it&rsquo;s also extremely useful when troubleshooting what went wrong when you are not watching the configuration as it is applied. Let me explain&#8230;<\/p>\n<p>Windows PowerShell will log the <b>Verbose<\/b>, <b>Error<\/b>, and <b>Debug<\/b> streams to the event log. If you need to troubleshoot why a configuration that ran in the past failed, you need to analyze the <b>Operational<\/b>, <b>Analytical<\/b>, and <b>Debug<\/b> logs under <b>Microsoft-Windows-DSC<\/b>. The Windows PowerShell team does an excellent job of detailing this in this post: <a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2014\/01\/03\/using-event-logs-to-diagnose-errors-in-desired-state-configuration.aspx\" target=\"_blank\">Using Event Logs to Diagnose Errors in Desired State Configuration<\/a>.<\/p>\n<p>It is a best practice to use <b>Write-Verbose<\/b>. I recommend keeping the verbose messages informational, but brief. You want them to be useful, but we&rsquo;ve all been through the pain of analyzing logs, so don&rsquo;t get crazy and overdo it.<\/p>\n<p>The <b>Get-TargetResource<\/b> function is much simpler than <b>Test-TargetResource<\/b>. This function will get the current state of the node that is being configured, but it is not used during the configuration process. The results must be returned in a hash table.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-5-12-15-2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-5-12-15-2.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>This example is straightforward. One thing to note is that I specified the <b>ErrorAction<\/b> parameter of <b>SilentlyContinue<\/b> because <b>Get-Item<\/b> will throw an error if a path isn&rsquo;t found. When this resource first runs, it&rsquo;s expected to not have an item&rsquo;s path, and I don&rsquo;t want to fill the logs with this error.<\/p>\n<p>The <b>Set-TargetResource<\/b> function is the function that is responsible for &ldquo;making it so.&rdquo; In Part 1 of this blog series, I recommended using the same parameter names in your resource as the parameter names of the cmdlets that you used in the resource. I recommended this so you can splat the parameters. Splatting is not only fun to say, it simplifies the code, making the <b>Test-TargetResource<\/b> function easy to develop.<\/p>\n<p style=\"margin-left:30px\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-5-12-15-3.png\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-5-12-15-3.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>This example first removes the parameters that don&rsquo;t exist for the cmdlets being used so I can splat <b>$PSBoundParameters<\/b>. You can see that I also add the <b>Force<\/b> parameter when <b>$Ensure<\/b> equals &ldquo;present&rdquo; (creating a new item) and the <b>Recurse<\/b> parameter when <b>$Ensure<\/b> is &ldquo;absent&rdquo; (removing an item). When you write the <b>Test-TargetResource<\/b> function, you want it to run without interactive input. This means that when the resource is running, it should NOT be waiting for a user to confirm an action.<\/p>\n<p>When you have all the <b>*-TargetResource<\/b> functions developed, I recommend that you start your testing by running the functions outside of the resource to confirm they perform as expected. Then test the resource from a configuration script. When you&rsquo;re ready to make your resource ready for prime-time, make sure you follow the design and testing checklist provided by the Windows PowerShell team: <a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2014\/11\/18\/powershell-dsc-resource-design-and-testing-checklist.aspx\" target=\"_blank\">PowerShell DSC Resource Design and Testing Checklist<\/a>.<\/p>\n<p>As I said early in this series, a DSC resource is simply a Windows PowerShell module. If you want to look at more examples of DSC resources, look in the <b>$PSModulePath<\/b> located here:<\/p>\n<p style=\"margin-left:30px\">C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\Modules\\PSDesiredStateConfiguration<\/p>\n<p>&#8230;and here:<\/p>\n<p style=\"margin-left:30px\">C:\\Program Files\\WindowsPowerShell\\Modules<\/p>\n<p>And that&rsquo;s all it takes to write your very own DSC resource.<\/p>\n<p>~Jason<\/p>\n<p>Thanks, Jason, for taking the time to share this series.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest blogger and Microsoft PFE, Jason Walker, talks about writing Get, Set, and Test TargetResource functions for DSC. Microsoft Scripting Guy, Ed Wilson, is here. Microsoft PFE and Honorary Scripting Guy, Jason Walker, is back with us today for Part 2 of his two-part series. Yesterday in Anatomy of a PowerShell DSC Resource, I [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,338,414,3,4,45],"class_list":["post-6201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-jason-walker","tag-providers","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Guest blogger and Microsoft PFE, Jason Walker, talks about writing Get, Set, and Test TargetResource functions for DSC. Microsoft Scripting Guy, Ed Wilson, is here. Microsoft PFE and Honorary Scripting Guy, Jason Walker, is back with us today for Part 2 of his two-part series. Yesterday in Anatomy of a PowerShell DSC Resource, I [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/6201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=6201"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/6201\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=6201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=6201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=6201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}