Tips

Self Aliased Functions in PowerShell

When we are working with an interactive shell, we use aliases for the frequently used cmdlets, and aliases are really useful and reduce the amount of keystrokes, and very simple and easy to use, and sometimes they can do magics  as well. It is not recommended to use the aliases in the scripts and functions as part of the best practices. We can create aliases to cmdlets and functions, end even to scripts using the New-Alias cmdlet… New-Alias -Name hello -Value Hello-Word And, we can also create aliases to the function at the time of declaration itself using [Alias("")] statement, we need to place it just before the parameters block param. Parameters block is mandatory, at least an empty block param() Function Hello-World { [Alias('hello','hey')] param ( [string] $Name ) Write-Host "Hello, $Name!" }


List and select in PowerShell console

In PowerShell, we use tab to navigate through the available CmdLets, parameters, parameter values and files or folders in a given path, but to list all of them and select the required CmdLet, parameter, value, file or folder you need to press Ctrl + Space to list and then use arrow keys to select the required, it even works with wildcard characters. Try it now…


PSCustomObject Using Select-Object

A traditional way of creating a PSCustomObject is as follows… $Emp = [pscustomobject] @{ Name = '' Department = '' Designation = '' } $Emp Output: Name Department Designation ---- ---------- ----------- Check the object type C:\> $Emp.GetType().Name Output: PSCustomObject And using Select-Object it is quite simple… $Emp = '' | Select-Object -Property Name, Department, Designation $Emp Output: Name Department Designation ---- ---------- ----------- Check the object type C:\> $Emp.GetType().Name Output: PSCustomObject


Get All The aliases By CmdLet

You can get the alias by name using Get-Alias with -Name parameter… Get-Alias -Name gci To get all the aliases of a CmdLet, use Get-Alias with -Definition parameter… Get-Alias -Definition Get-ChildItem


Convert A String To Title Case

Converting a string to upper and lower cases are possible with the string object using the dot notation, but not sure why title case is not directly supported yet with the string object in PowerShell, however there are a couple of ways to achieve the same… $Text = 'kiran patnayakuni' # Using PowerShell (Get-Culture).TextInfo.ToTitleCase($Text) #Using .Net [cultureinfo]::CurrentCulture.TextInfo.ToTitleCase($Text)


Overload Definitions of a Method

To refer the overload definitions/syntax of a method of an object using the OverloadDefinitions property of a method with simple dot notation, or simply use the method name without the parenthesis (). <object>.<method>.OverloadDefinitions # or <object>.<method> Example: $Text = "PowerShell" # To see all the methods of an object $Text | Get-Member -MemberType *Method $Text.LastIndexOf # or $Text.LastIndexOf.OverloadDefinitions


DateTime From World Clock API

A simple REST API get method call to retrieve the datetime from http://worldclockapi.com service. <# This script returns the current date time from http://worldclockapi.com/ using REST API service. You can find the latest uri from the site above. Eastern Standard Time http://worldclockapi.com/api/json/est/now Coordinated Universal Time http://worldclockapi.com/api/json/utc/now Also supports JSONP Central European Standard Time http://worldclockapi.com/api/jsonp/cet/now?callback=mycallback #> # utc time url [string] $WorldClockAPIUrl = 'http://worldclockapi.com/api/json/utc/now' # Invoke Get method. The API returns the output in json format, but by default Invoke-RestMethod will convert from JSON to readable format (pacustomobject) [psobject] $ApiResult = Invoke-RestMethod -Method Get -Uri $WorldClockAPIUrl <# Selecting only current datetime from the api output $id : 1 currentDateTime : 2019-02-27T11:51Z utcOffset : 00:00:00 isDayLightSavingsTime : False dayOfTheWeek : Tuesday timeZoneName : UTC currentFileTime : 131957418910000000 ordinalDate : 2019-58 serviceResponse : #> [string] $UTCTimeString = $ApiResult.currentDateTime # Convert the string to datetime using .Net datetime class method Parse(), and returns datetime in default culture [datetime]$DateTime = [System.DateTime]::Parse($UTCTimeString) # output datetime return $DateTime


Zip & Unzip

Prior to Windows PowerShell 5.0, if you want to zip or unzip the files you have to depend on COM objects, but from version 5.0 onwards (it is even available in PowerShell Core as well) there are two new cmdlets Compress-Archive and Expand-Archive are introduced to zip & unzip the files respectively. Examples: ### Examples are from Microsoft Docs ## Zip the files # Example 1: Create an archive file Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip # Example 2: Create an archive with wildcard characters Compress-Archive -Path C:\Reference\* -CompressionLevel Fastest -DestinationPath C:\Archives\Draft # Example 3: Update an existing archive file Compress-Archive -Path C:\Reference\* -Update -DestinationPath C:\Archives\Draft.Zip # Example 4: Create an archive from an entire folder Compress-Archive -Path C:\Reference -DestinationPath C:\Archives\Draft ## Unzip the file # Example 1: Extract the contents of an archive Expand-Archive -LiteralPath C:\Archives\Draft.Zip -DestinationPath C:\Reference # Example 2: Extract the contents of an archive in the current folder Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference


Prompt for choice

Sometimes in the interactive session when we are executing the scripts, and where it requires an input/consent from the user to proceed further we can prompt the user to choose from the given choices… # PromptForChoice Args $Title = "Do you want to proceed further?" $Prompt = "Enter your choice" $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @("&Yes", "&No", "&Cancel") $Default = 1 # Prompt for the choice $Choice = $host.UI.PromptForChoice($Title, $Prompt, $Choices, $Default) # Action based on the choice switch($Choice) { 0 { Write-Host "Yes - Write your code"} 1 { Write-Host "No - Write your code"} 2 { Write-Host "Cancel - Write your code"} }


Select-Object With Calculated Properties In PowerShell.

When selecting properties using Select-Object, sometimes we may need to fetch the values in a more meaningful and understandable format, and in some cases, conditional output may be needed to get the precise output, you can achieve the same by using the expressions directly in the same select statement or using splatting… # Get the total memory in GB from the local computer using the calculated property with Select-Object Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property PSComputerName, ` @{Name = 'Memory in GB'; Expression = {[Math]::Round($_.TotalVisibleMemorySize/1MB)}} <# Output PSComputerName Memory in GB -------------- ------------ Workstation 8 #> # Get the services where the names are starting with App, and display IsRunning with Yes/No using the calculated property $IsRunning = @{ Label = "IsRunning" Expression = { if($_.Status -eq 'Running') { "Yes" } else { "No" } } } Get-Service -Name App* | Select-Object -Property Name, DisplayName, $IsRunning <# Output Name DisplayName IsRunning ---- ----------- --------- AppIDSvc Application Identity No Appinfo Application Information Yes AppMgmt Application Management No AppReadiness App Readiness No AppVClient Microsoft App-V Client No AppXSvc AppX Deployment Service (AppXSVC) No #>


Download a zip file from the internet and extract using PowerShell.

The code below will download the .zip file from the internet, then extracts the files from the zip and opens the extracted folder… $Url = 'https://download.sysinternals.com/files/BGInfo.zip' $ZipFile = 'C:\ZipFolder\' + $(Split-Path -Path $Url -Leaf) $Destination= 'C:\Extracted\' Invoke-WebRequest -Uri $Url -OutFile $ZipFile $ExtractShell = New-Object -ComObject Shell.Application $Files = $ExtractShell.Namespace($ZipFile).Items() $ExtractShell.NameSpace($Destination).CopyHere($Files) Start-Process $Destination


$Args in PowerShell

In scripting, there are many things to experience in many ways, the traditional way is always the best practice though, the formal way is always an option… Function Add { param ( [Parameter(Mandatory=$true)] [int] $Number1, [Parameter(Mandatory=$true)] [int] $Number2 ) [int] $Sum = 0 $Sum = $Number1 + $Number2 return, $Sum } Add -Number1 4 -Number2 5 Formal way $Add = {$args[0] + $args[1]} . $Add 4 5


#requires -RunAsAdministrator

When PowerShell requires to execute the script with elevated permissions then add #requires statement in the beginning of the code… #requires -RunAsAdministrator Set-ExecutionPolicy -ExecutionPolicy Unrestricted For more details about #requires, run the help command below… Get-Help about_requires


PowerShell Version

Know your PowerShell Version PS C:\Users\kiran> $PSVersionTable.PSVersion Major Minor Build Revision ----- ----- ----- -------- 5 1 17763 134 PS C:\Users\kiran> (Get-Host).Version Major Minor Build Revision ----- ----- ----- -------- 5 1 17763 134 PS C:\Users\kiran> $Host.Version Major Minor Build Revision ----- ----- ----- -------- 5 1 17763 134