Saturday, April 30, 2016

Use Get-CommandVariable to auto generate variables for a command

In this post, I want to share a silly new PowerShell command Get-CommandVariable that I wrote and it is available on github as a powershell module and you can put inside your modules folder and start using it.  “What problem this is trying to solve?” you might be thinking.

You start writing a powershell script and you want to pass variables to a command.  For example, you want to create a new AzureRM Web app using command New-AzureRMWebApp. Then you will have to write your command like this using $variables.

$ResourceGroupName = "mycustomresourcegroup"
$Name = "webapp01"
$Location = "centralus"

New-AzureRMWebApp  -ResourceGroupName $ResourceGroupName -Name $Name -Location $Location

Let’s understand what you had to go through. Type all the parameters and its variables with a $sign.  Copy those variables at the top so you can initialize them. That’s not the tricky part. The thing that gets me the most is trying to think names for those variables and then copy the variables at the top.

So Get-CommandVariable will create this all for you.  How?  Just specify for which command you want to generate automatic $variables and it will do it. In the below example, we are using New-AzureRMWebApp command and after it generates the output,  I just copy the text and put it inside ISE window.

PS C:>Get-CommandVariable –CommandName New-AzureRMWebApp
$ResourceGroupName = ""
$Name = ""
$Location = ""
New-AzureRMWebApp -ResourceGroupName $ResourceGroupName -Name $Name -Location $Location

If you are using powershell for quite a long time you may know that powershell commands have certain parameters as mandatory and others are not mandatory.  Then there are commands that will work different combination of parameters. And Get-CommandVariable will work in those scenarios as well.

For example, if you provide –ShowAll option it will generate variables for all the parameters not just mandatory ones.

PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount -ListParameterSets
$StorageAccountName = ""
$Label = ""
$Description = ""
$AffinityGroup = ""
$Type = ""
$Profile = ""

New-AzureStorageAccount  -StorageAccountName $StorageAccountName -Label $Label -Description $Description -AffinityGroup $AffinityGroup -Type $Type -Profile $Profile

You can specify to list all the ParameterSets (think: different combinations of parameters) that a particular command expects. For example,

PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount -ListParameterSets
Name
----
ParameterSetAffinityGroup
ParameterSetLocation

Then you can tell Get-CommandVariable to generate variables for a particular ParameterSet. In the below example we are chosing ParameterSetAffinityGroup
PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount  -ParameterSetName ParameterSetAffinityGroup
$StorageAccountName = ""
$AffinityGroup = ""

New-AzureStorageAccount  -StorageAccountName $StorageAccountName -AffinityGroup $AffinityGroup
By default, I am showing just the mandatory parameters, since my goal to get going as quickly as possible. To show all parameters you will have to provide –ShowAll flag. So that’s it and if you think this might be useful to you then give it a try. You can provide feedback in the comments below or submit issues directly on github as well.

Sunday, April 3, 2016

PowerShell Tip: Start-Transcript and Stop-Transcript

You are trying to write a powershell script but you don’t know all the right comands to execute and what parameters to pass.  So you write a bunch of commands, out of which many don’t work and some work. After lots of experimentation you finally find the right commands with right parameters that would work for your script. You can do Get-history to get a list of all the commands that were executed. But that history only gets persisted as long as you have the powershell window open. Once you close the window that history is gone. I have closed the console window many times and found myself cursing for having done so because I couldn’t remember those commands. Now I have to again fiddle with those commands. Wouldn’t it be nice if there was something that would record everything you did in a text file? Once you are done experimenting you could tell it to stop recording your session and then you can use that text file for later reference. 
Start-Transcript and Stop-Transcript does just that. Before you start experimenting just tell PowerShell you want to record stuff in a text file and Start-Transcript will do that.  After you are done you can use Stop-Transcript to stop recording.  I like this feature. But there is more.
See in the Start-Transcript you have to provide a txt file and I don’t like providing path information with a uniquename everytime I want to do Start-Transcript and I want it to be automatic.  Below function will create a uniquename of the file based upon a timestamp. Now if you wish to provide a meaningful name then you can do that too. The script will append a unique timestamp to that name.  You can put this function into your profile and it will be available to you when the console loads.
function start-recording {
param(
 [string]$sessName
)
try { stop-transcript } catch {}
$uniqFileName = (get-Date).ToString('MMddyyyyhhmmss');
if([System.String]::IsNullOrEmpty($sessName)){
 Start-Transcript -Path "C:\Scripts\Transcripts\$uniqFileName.txt" -NoClobber 
}
else{
Start-Transcript -Path "C:\Scripts\Transcripts\$sessName$uniqFileName.txt" -NoClobber  
}
}

set-alias stop-recording stop-transcript 
I invoke command -  Start-Recording “webpackge” and a unique file name is created in my scripts/transcripts folder by that name.  The function also does stop-transcript if you execute the function start-recording again so it does saves existing session and starts recording another one.