We are pleased to announce the second preview of PowerShell Crescendo, a framework to rapidly develop PowerShell cmdlets for native commands, regardless of platform.
The updated preview releases are now available for download on the PowerShell Gallery:
To install Microsoft.PowerShell.Crescendo:
Install-Module Microsoft.PowerShell.Crescendo -AllowPrerelease
For more information on Microsoft.PowerShell.Crescendo, check out these previous blog posts:
- Announcing PowerShell Crescendo Preview.1
- Native Commands in PowerShell Part 1
- Native Commands in PowerShell Part 2
Crescendo Preview 2 Updates
This update to Crescendo adds elevation support for native commands, and generation of a module manifest when exporting a Crescendo module. Read the full list of changes below:
- Added support for native command elevation on Windows and Linux platforms. (Issue #50)
Export-CrescendoModule
now exports a module manifest (psd1
) along with the module file (psm1
). (Issue #51)- Added support for generating aliases for Crescendo cmdlets (Issue #52)
- Added support for
SupportsShouldProcess
. Thanks jdhitsolutions! (Issue #59)
Native Command elevation
Native commands may require administrative elevation to perform the requested operation. The
Crescendo schema has been extended to support elevation on Windows and Linux/macOS platforms. The schema
supports the new keyword Elevation that has two properties Command
and Arguments
.
- Command: Defines the elevation mechanism to be used to elevate the native command. The function
Invoke-WindowsNativeAppWithElevation
has been included to aid with elevation on Windows.sudo
has been tested as well. - Arguments: These are the parameters to be used in conjunction with the elevation command. This can
be a collection of parameters.
- OriginalName: This is the parameter to be used with the elevation command.
- DefaultValue: The default parameter value.
Windows Native Command Elevation
Elevation on Windows is supported using the built-in function
Invoke-WindowsNativeAppWithElevation
. Invoke-WindowsNativeAppWithElevation
uses Start-Process
with a PSCredential
to invoke the native command and captures the output and errors of the native
command which are returned to the user. This function is inserted into the Crescendo module you
export. In the example below, the PowerShell cmdlet Get-Credential
will prompt for credentials
necessary to elevate the native command when the exported Crescendo function is executed.
"Elevation": {
"Command": "Invoke-WindowsNativeAppWithElevation",
"Arguments": [
{
"OriginalName" : "-Credential",
"DefaultValue": "(get-credential)"
}
]
},
In automation scenarios that require elevation without user interaction, Crescendo supports retrieving credentials from secured vaults. In the example below, credentials for elevation are retrieved from SecretManagement and SecretStore.
For more information about storing and managing secrets, see [SecretManagement Announcement](https://devblogs.microsoft.com/powershell/secretmanagement-and-secretstore-are-generally-available/
"Elevation": {
"Command": "Invoke-WindowsNativeAppWithElevation",
"Arguments": [
{
"OriginalName" : "-Credential",
"DefaultValue": "(get-secret admin)"
}
]
},
Elevation can be defined for each cmdlet. When authoring a Crescendo json
configuration, include
the elevation definition before the parameters are defined. In the example below, the native command
netsh.exe
requires elevation to enable and disable the Windows Firewall.
{
"$schema": "./Microsoft.PowerShell.Crescendo.Schema.json",
"Verb": "Set",
"Noun": "WinFirewall",
"Platform": ["Windows"],
"OriginalCommandElements": ["advfirewall", "set", "allprofiles", "state"],
"OriginalName": "$env:Windir/system32/netsh.exe",
"Elevation": {
"Command": "Invoke-WindowsNativeAppWithElevation",
"Arguments": [
{
"OriginalName" : "-Credential",
"DefaultValue": "(get-credential)"
}
]
},
"DefaultParameterSetName": "Enable",
"Parameters": [
{
"OriginalName": "on",
"Name": "On",
"ParameterType": "switch",
"ParameterSetName": ["Enable"]
},
{
"OriginalName": "off",
"Name": "Off",
"ParameterType": "switch",
"ParameterSetName": ["Disable"]
}
]
}
Linux Native Command Elevation
Native command elevation for Linux and macOS is handled through the command sudo
. To enable
elevation for Crescendo, include sudo
as the Command value. In the example below, when the
function Get-TimeServer
is executed, the user is prompted for the sudo
password. The native
command is elevated with sudo privileges. In automation scenarios that require elevation without
user interaction, configure the sudoers
file.
{
"$schema": "../src/Microsoft.PowerShell.Crescendo.Schema.json",
"Verb": "Get",
"Noun": "TimeServer",
"Elevation": {
"Command": "sudo"
},
"OriginalCommandElements": ["-getnetworktimeserver"],
"OriginalName": "/usr/sbin/systemsetup",
"Platform": ["MacOS"],
"OutputHandlers": [
{
"ParameterSetName": "Default",
"Handler": "$args|%{[pscustomobject]@{ TimeServer = $_.Split(':')[1].Trim()}}"
}
]
}
SupportsShouldProcess
Cmdlets that cause change to the system, such as files and service configurations, create a risk
that could negatively impact operations. To help mitigate risk, cmdlets support common parameters
-WhatIf and -Confirm. These parameters provide greater detail about the target of each
change, and provides a confirmation mechanism allowing the user to approve each change. Crescendo
supports this functionality when wrapping native commands though the schema keyword
SupportsShouldProcess
.
In the example below, The keyword SupportsShouldProcess
accepts a boolean to enable the common
parameters -WhatIf and -Confirm.
{
"$schema": "../src/Microsoft.PowerShell.Crescendo.Schema.json",
"Verb": "Remove",
"Noun": "DockerImage",
"OriginalName": "docker",
"SupportsShouldProcess": true,
"OriginalCommandElements": [
"image",
"rm"
],
"Parameters": [
{
"Name": "ID",
"OriginalName": "",
"Mandatory": true,
"ValueFromPipelineByPropertyName": true
}
]
}
Executing Remove-DockerImage
with the -WhatIf parameter supported by SupportsShouldProcess
.
Get-DockerImage | Where-Object {$_.id -match "d70eaf7277ea"} | Remove-DockerImage -WhatIf
When SupportsShouldProcess
is set True, the following expected output will result.
What if: Performing the operation "Remove-DockerImage" on target "docker image rm d70eaf7277ea".
Aliases
Aliases for Crecendo wrapped native commands are now supported in the Crescendo schema with the
keyword Aliases
. In the snippet below, the cmdlet definition Set-WinFirewall
includes the alias
definition SFW
. When exported, the Crescendo created module will include the Set-WinFirewall
function and SFW
alias.
{
"$schema": "./Microsoft.PowerShell.Crescendo.Schema.json",
"Verb": "Set",
"Noun": "WinFirewall",
"Platform": ["Windows"],
"OriginalCommandElements": ["advfirewall", "set", "allprofiles", "state"],
"OriginalName": "$env:Windir/system32/netsh.exe",
"Aliases": ["SFW"],
"Elevation": {
"Command": "Invoke-WindowsNativeAppWithElevation",
"Arguments": [
{
"OriginalName" : "-Credential",
"DefaultValue": "(get-credential)"
}
]
},
Future plans
Next/Future plans for preview.3 will be based on feedback and include a few items under investigation:
- Improved OutputHandler support for building objects from native command string output.
- Support for multiple cmdlet definitions in a single
json
configuration.
Our goal is to make it easier to convert your native commands to PowerShell cmdlets and receive the benefits that PowerShell provides. We value your ideas and feedback and hope you will give Crescendo a try, then stop by our GitHub repository and let us know of any issues or features you would like added.
For more information about PowerShell Crescendo issues and features, see: Crescendo on GitHub
Jason Helmick
Program Manager, PowerShell
Awesome. This should cover more use cases.
I think Crescendo should be providing option to have -Credential to the cmdlets it creates using the same Parameter attributes via json,
which can utilize the Invoke-WindowsNativeAppWithElevation. Otherwise its either using a secret store or purely interactive(correct me if I'm wrong).
Is there any reason why the elevation function looks like a cmdlet (Invoke-WindowsNativeAppWithElevation) than a simple usage like sudo for linux. If that cmdlet is always used internally, then...