Last week I posted a function you can use in the Windows PowerShell ISE to convert aliases to command definitions. My script relied on regular expressions to seek out and replace aliases. A number of people asked me why I didn't use the PowerShell tokenizer. My answer was that because I'm not a developer and don't think that way. But after working a bit with it I can see the value so I have another function you can use in the ISE to convert aliases to commands.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
This function, ConvertFrom-Alias, will parse a complete script in the ISE and replace all aliases with their command line definitions.
[cc lang="PowerShell"]
Function ConvertFrom-Alias {
Param (
[Parameter(Position=0)]
[ValidateNotNullorEmpty()]
$Text=$psISE.CurrentFile.Editor.text
)
#make sure we are using the ISE
if ($host.name -match "ISE")
{
#Turn the script into syntax tokens
Write-Verbose "Tokenizing"
#verify there are no syntax errors first by Tokenizing the script
$out=$null
$tokens = [System.Management.Automation.PSparser]::Tokenize($text, [ref]$out)
#if there are errors they will be directed to $out
if ($out)
{
#enumerate each parsing error in $out
foreach ($problem in $out) {
Write-Warning $problem.message
Write-Warning "Line: $($problem.Token.Startline) at character: $($problem.token.StartColumn)"
}
}
else
{
#if no errors then proceed to convert
$tokens | Where-Object { $_.Type -eq 'Command'} |
Sort-Object StartLine, StartColumn -Descending |
ForEach-Object {
#handle the ? by escaping it
if($_.content -eq '?')
{
Write-Verbose "Found a ?"
$result = Get-Command -name '`?' -CommandType Alias
}
else
{
$result = Get-Command -name $_.Content -CommandType Alias -ErrorAction SilentlyContinue
}
#check and see if Get-Command returned anything
if($result)
{
#find each command and insert the corresponding command definition
Write-Verbose "Replacing $($result.name) with $($result.definition)"
$psISE.CurrentFile.Editor.Select($_.StartLine,$_.StartColumn,$_.EndLine,$_.EndColumn)
$psISE.CurrentFile.Editor.InsertText($result.Definition)
}
} #foreach
} #else $tokens exists and there were no parsing errors
} #if ISE
else
{
Write-Warning "You must be using the PowerShell ISE"
}
Write-Verbose "Finished"
} #end Function
[/cc]
There is one primary difference between this and my regular expression version. This function processes the entire file and the regular expression version allows you to process selected text, so you may have a need for both. The other difference is that when using the tokenizer your script can't have any parsing errors. The function tokenizes the script and if there are errors writes results to the warning pipeline.
[cc lang="Powershell"]
#verify there are no syntax errors first by Tokenizing the script
$out=$null
$tokens = [System.Management.Automation.PSparser]::Tokenize($text, [ref]$out)
#if there are errors they will be directed to $out
if ($out)
{
#enumerate each parsing error in $out
foreach ($problem in $out) {
Write-Warning $problem.message
Write-Warning "Line: $($problem.Token.Startline) at character: $($problem.token.StartColumn)"
}
}
[/cc]
Tokenizing, by the way, is PowerShell's way of identifying the command elements so it can construct a pipelined expression. At least that's enough of a definition for our purposes. Assuming no errors, the tokens are processed with ForEach-Object.
[cc lang="PowerShell"]
$tokens | Where-Object { $_.Type -eq 'Command'} |
Sort-Object StartLine, StartColumn -Descending |
ForEach-Object {
[/cc]
The function looks for aliases in token content.
[cc lang="PowerShell"]
$result = Get-Command -name $_.Content -CommandType Alias -ErrorAction SilentlyContinue
[/cc]
If if finds one, the corresponding text is replaced in the file.
[cc lang="PowerShell"]
#check and see if Get-Command returned anything
if($result)
{
#find each command and insert the corresponding command definition
Write-Verbose "Replacing $($result.name) with $($result.definition)"
$psISE.CurrentFile.Editor.Select($_.StartLine,$_.StartColumn,$_.EndLine,$_.EndColumn)
$psISE.CurrentFile.Editor.InsertText($result.Definition)
}
[/cc]
The end result is that the function finds the alias from the token and replaces it with the command. Very slick and pretty quick. You can add this script to your profile and menu my other ISE tools. Just remember that that processes the entire script and it must be free of syntax errors.
Download ConvertFrom-Alias and let me know what you think.