{"id":19000,"date":"2021-05-06T07:24:25","date_gmt":"2021-05-06T15:24:25","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/powershell\/?p=19000"},"modified":"2021-11-06T11:39:13","modified_gmt":"2021-11-06T19:39:13","slug":"announcing-powershell-crescendo-preview-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/announcing-powershell-crescendo-preview-2\/","title":{"rendered":"Announcing PowerShell Crescendo Preview.2"},"content":{"rendered":"<p>We are pleased to announce the second preview of <strong>PowerShell Crescendo<\/strong>, a framework to rapidly\ndevelop PowerShell cmdlets for native commands, regardless of platform.<\/p>\n<p>The updated preview releases are now available for download on the PowerShell Gallery:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.powershellgallery.com\/packages\/Microsoft.PowerShell.Crescendo\/0.5.1\">Microsoft.PowerShell.Crescendo Preview 2<\/a><\/li>\n<\/ul>\n<p>To install <strong>Microsoft.PowerShell.Crescendo<\/strong>:<\/p>\n<pre><code class=\"language-powershell\">Install-Module Microsoft.PowerShell.Crescendo -AllowPrerelease<\/code><\/pre>\n<p>For more information on <strong>Microsoft.PowerShell.Crescendo<\/strong>, check out these previous blog posts:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/announcing-powershell-crescendo-preview-1\/\">Announcing PowerShell Crescendo Preview.1<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/native-commands-in-powershell-a-new-approach\/\">Native Commands in PowerShell Part 1<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/native-commands-in-powershell-a-new-approach-part-2\/\">Native Commands in PowerShell Part 2<\/a><\/li>\n<\/ul>\n<h2>Crescendo Preview 2 Updates<\/h2>\n<p>This update to Crescendo adds elevation support for native commands, and generation of a module\nmanifest when exporting a Crescendo module. Read the full list of changes below:<\/p>\n<ul>\n<li>Added support for native command elevation on Windows and Linux platforms. (<a href=\"https:\/\/github.com\/PowerShell\/Crescendo\/issues\/50\">Issue #50<\/a>)<\/li>\n<li><code>Export-CrescendoModule<\/code> now exports a module manifest (<code>psd1<\/code>) along with the module file (<code>psm1<\/code>). (<a href=\"https:\/\/github.com\/PowerShell\/Crescendo\/issues\/51\">Issue #51<\/a>)<\/li>\n<li>Added support for generating aliases for Crescendo cmdlets (<a href=\"https:\/\/github.com\/PowerShell\/Crescendo\/issues\/52\">Issue #52<\/a>)<\/li>\n<li>Added support for <code>SupportsShouldProcess<\/code>. Thanks jdhitsolutions! (<a href=\"https:\/\/github.com\/PowerShell\/Crescendo\/issues\/59\">Issue #59<\/a>)<\/li>\n<\/ul>\n<h2>Native Command elevation<\/h2>\n<p>Native commands may require administrative elevation to perform the requested operation. The\nCrescendo schema has been extended to support elevation on Windows and Linux\/macOS platforms. The schema\nsupports the new keyword <strong>Elevation<\/strong> that has two properties <code>Command<\/code> and <code>Arguments<\/code>.<\/p>\n<ul>\n<li>Command: Defines the elevation mechanism to be used to elevate the native command. The function\n<code>Invoke-WindowsNativeAppWithElevation<\/code> has been included to aid with elevation on Windows. <code>sudo<\/code>\nhas been tested as well.<\/li>\n<li>Arguments: These are the parameters to be used in conjunction with the elevation command. This can\nbe a collection of parameters.<\/p>\n<ul>\n<li>OriginalName: This is the parameter to be used with the elevation command.<\/li>\n<li>DefaultValue: The default parameter value.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Windows Native Command Elevation<\/h2>\n<p>Elevation on Windows is supported using the built-in function\n<code>Invoke-WindowsNativeAppWithElevation<\/code>. <code>Invoke-WindowsNativeAppWithElevation<\/code> uses <code>Start-Process<\/code>\nwith a <code>PSCredential<\/code> to invoke the native command and captures the output and errors of the native\ncommand which are returned to the user. This function is inserted into the Crescendo module you\nexport. In the example below, the PowerShell cmdlet <code>Get-Credential<\/code> will prompt for credentials\nnecessary to elevate the native command when the exported Crescendo function is executed.<\/p>\n<pre><code class=\"language-json\">\"Elevation\": {\r\n        \"Command\": \"Invoke-WindowsNativeAppWithElevation\",\r\n        \"Arguments\": [\r\n            {\r\n                \"OriginalName\" : \"-Credential\",\r\n                \"DefaultValue\": \"(get-credential)\"\r\n            }\r\n        ]\r\n    },<\/code><\/pre>\n<p>In automation scenarios that require elevation without user interaction, Crescendo supports\nretrieving credentials from secured vaults. In the example below, credentials for elevation are\nretrieved from SecretManagement and SecretStore.<\/p>\n<p>For more information about storing and managing secrets, see [SecretManagement Announcement](https:\/\/devblogs.microsoft.com\/powershell\/secretmanagement-and-secretstore-are-generally-available\/<\/p>\n<pre><code class=\"language-json\">\"Elevation\": {\r\n        \"Command\": \"Invoke-WindowsNativeAppWithElevation\",\r\n        \"Arguments\": [\r\n            {\r\n                \"OriginalName\" : \"-Credential\",\r\n                \"DefaultValue\": \"(get-secret admin)\"\r\n            }\r\n        ]\r\n    },<\/code><\/pre>\n<p>Elevation can be defined for each cmdlet. When authoring a Crescendo <code>json<\/code> configuration, include\nthe elevation definition before the parameters are defined. In the example below, the native command\n<code>netsh.exe<\/code> requires elevation to enable and disable the Windows Firewall.<\/p>\n<pre><code class=\"language-json\">{\r\n    \"$schema\": \".\/Microsoft.PowerShell.Crescendo.Schema.json\",\r\n    \"Verb\": \"Set\",\r\n    \"Noun\": \"WinFirewall\",\r\n    \"Platform\": [\"Windows\"],\r\n    \"OriginalCommandElements\": [\"advfirewall\", \"set\", \"allprofiles\", \"state\"],\r\n    \"OriginalName\": \"$env:Windir\/system32\/netsh.exe\",\r\n    \"Elevation\": {\r\n        \"Command\": \"Invoke-WindowsNativeAppWithElevation\",\r\n        \"Arguments\": [\r\n            {\r\n                \"OriginalName\" : \"-Credential\",\r\n                \"DefaultValue\": \"(get-credential)\"\r\n            }\r\n        ]\r\n    },\r\n    \"DefaultParameterSetName\": \"Enable\",\r\n    \"Parameters\": [\r\n        {\r\n            \"OriginalName\": \"on\",\r\n            \"Name\": \"On\",\r\n            \"ParameterType\": \"switch\",\r\n            \"ParameterSetName\": [\"Enable\"]\r\n        },\r\n        {\r\n            \"OriginalName\": \"off\",\r\n            \"Name\": \"Off\",\r\n            \"ParameterType\": \"switch\",\r\n            \"ParameterSetName\": [\"Disable\"]\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<h2>Linux Native Command Elevation<\/h2>\n<p>Native command elevation for Linux and macOS is handled through the command <code>sudo<\/code>. To enable\nelevation for Crescendo, include <code>sudo<\/code> as the <strong>Command<\/strong> value. In the example below, when the\nfunction <code>Get-TimeServer<\/code> is executed, the user is prompted for the <code>sudo<\/code> password. The native\ncommand is elevated with sudo privileges. In automation scenarios that require elevation without\nuser interaction, configure the <code>sudoers<\/code> file.<\/p>\n<pre><code class=\"language-json\">{\r\n    \"$schema\": \"..\/src\/Microsoft.PowerShell.Crescendo.Schema.json\",\r\n    \"Verb\": \"Get\",\r\n    \"Noun\": \"TimeServer\",\r\n    \"Elevation\": {\r\n        \"Command\": \"sudo\"\r\n    },\r\n    \"OriginalCommandElements\": [\"-getnetworktimeserver\"],\r\n    \"OriginalName\": \"\/usr\/sbin\/systemsetup\",\r\n    \"Platform\": [\"MacOS\"],\r\n    \"OutputHandlers\": [\r\n        {\r\n            \"ParameterSetName\": \"Default\",\r\n            \"Handler\": \"$args|%{[pscustomobject]@{ TimeServer = $_.Split(':')[1].Trim()}}\"\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<h2>SupportsShouldProcess<\/h2>\n<p>Cmdlets that cause change to the system, such as files and service configurations, create a risk\nthat could negatively impact operations. To help mitigate risk, cmdlets support common parameters\n<strong>-WhatIf<\/strong> and <strong>-Confirm<\/strong>. These parameters provide greater detail about the target of each\nchange, and provides a confirmation mechanism allowing the user to approve each change. Crescendo\nsupports this functionality when wrapping native commands though the schema keyword\n<code>SupportsShouldProcess<\/code>.<\/p>\n<p>In the example below, The keyword <code>SupportsShouldProcess<\/code> accepts a boolean to enable the common\nparameters <strong>-WhatIf<\/strong> and <strong>-Confirm<\/strong>.<\/p>\n<pre><code class=\"language-json\">{\r\n    \"$schema\": \"..\/src\/Microsoft.PowerShell.Crescendo.Schema.json\",\r\n    \"Verb\": \"Remove\",\r\n    \"Noun\": \"DockerImage\",\r\n    \"OriginalName\": \"docker\",\r\n    \"SupportsShouldProcess\": true,\r\n    \"OriginalCommandElements\": [\r\n        \"image\",\r\n        \"rm\"\r\n    ],\r\n    \"Parameters\": [\r\n        {\r\n            \"Name\": \"ID\",\r\n            \"OriginalName\": \"\",\r\n            \"Mandatory\": true,\r\n            \"ValueFromPipelineByPropertyName\": true\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<p>Executing <code>Remove-DockerImage<\/code> with the <strong>-WhatIf<\/strong> parameter supported by <code>SupportsShouldProcess<\/code>.<\/p>\n<pre><code class=\"language-powershell\">Get-DockerImage | Where-Object {$_.id -match \"d70eaf7277ea\"} | Remove-DockerImage -WhatIf<\/code><\/pre>\n<p>When <code>SupportsShouldProcess<\/code> is set <strong>True<\/strong>, the following expected output will result.<\/p>\n<pre><code class=\"language-output\">What if: Performing the operation \"Remove-DockerImage\" on target \"docker image rm d70eaf7277ea\".<\/code><\/pre>\n<h2>Aliases<\/h2>\n<p>Aliases for Crecendo wrapped native commands are now supported in the Crescendo schema with the\nkeyword <code>Aliases<\/code>. In the snippet below, the cmdlet definition <code>Set-WinFirewall<\/code> includes the alias\ndefinition <code>SFW<\/code>. When exported, the Crescendo created module will include the <code>Set-WinFirewall<\/code>\nfunction and <code>SFW<\/code> alias.<\/p>\n<pre><code class=\"language-json\">{\r\n    \"$schema\": \".\/Microsoft.PowerShell.Crescendo.Schema.json\",\r\n    \"Verb\": \"Set\",\r\n    \"Noun\": \"WinFirewall\",\r\n    \"Platform\": [\"Windows\"],\r\n    \"OriginalCommandElements\": [\"advfirewall\", \"set\", \"allprofiles\", \"state\"],\r\n    \"OriginalName\": \"$env:Windir\/system32\/netsh.exe\",\r\n    \"Aliases\": [\"SFW\"],\r\n    \"Elevation\": {\r\n        \"Command\": \"Invoke-WindowsNativeAppWithElevation\",\r\n        \"Arguments\": [\r\n            {\r\n                \"OriginalName\" : \"-Credential\",\r\n                \"DefaultValue\": \"(get-credential)\"\r\n            }\r\n        ]\r\n    },<\/code><\/pre>\n<h2>Future plans<\/h2>\n<p>Next\/Future plans for preview.3 will be based on feedback and include a few items under investigation:<\/p>\n<ul>\n<li>Improved OutputHandler support for building objects from native command string output.<\/li>\n<li>Support for multiple cmdlet definitions in a single <code>json<\/code> configuration.<\/li>\n<\/ul>\n<p>Our goal is to make it easier to convert your native commands to PowerShell cmdlets and receive the\nbenefits that PowerShell provides. We value your ideas and feedback and hope you will give Crescendo\na try, then stop by our GitHub repository and let us know of any issues or features you would like\nadded.<\/p>\n<p>For more information about <strong>PowerShell Crescendo<\/strong> issues and features, see:\n<a href=\"https:\/\/github.com\/PowerShell\/Crescendo\">Crescendo on GitHub<\/a><\/p>\n<p>Jason Helmick<\/p>\n<p>Program Manager, PowerShell<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many native commands require elevated privileges to perform the expected operations. PowerShell Crescendo Preview 2 now supports cross platform elevation for your Crescendo wrapped native commands.<\/p>\n","protected":false},"author":7527,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3173],"class_list":["post-19000","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-powershell-crescendo"],"acf":[],"blog_post_summary":"<p>Many native commands require elevated privileges to perform the expected operations. PowerShell Crescendo Preview 2 now supports cross platform elevation for your Crescendo wrapped native commands.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/19000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/7527"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=19000"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/19000\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=19000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=19000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=19000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}