# Tahir Hassan's Blog

My Technical Notes

## Friday, 19 October 2012

### Various Techniques for Powershell

#### Getting History

To get a history of all commands executed within your Powershell sessions do the following:


Get-History | Select CommandLine > "C:\Temp\script1.ps1"


This is useful because it allows you to interactively build your code, and once you have finished you can use the above command to dump it into a file and then re-run later.

The default number of commands it keeps is 64, to change it, set the $MaximumHistoryCount to something larger. #### Executing an anonymous block Use the & operator followed by the code block and then by the argument:  PS> & { param($name) Write-Host $name } 'Tahir' Tahir  #### Expression and Variable Expansion in Strings Double Quoted Strings allow expansion but single quoted strings do not:  PS>$name = 'Tahir Hassan';
PS> 'My Name is $name' My Name is$name
PS> "My Name is $name" My Name is Tahir Hassan  Therefore it is desirable to use single-quoted strings unless there is a need for expansion. To expand a section of code, we wrap it in$() (useful for accessing properties):


PS> $tahir = @{ 'Name' = 'Tahir'; 'BlogUrl' = 'tahirhassan.blogspot.co.uk' } PS> "My name is$( $tahir.Name ) and my blog can be found at$( $tahir.BlogUrl )" My name is Tahir and my blog can be found at tahirhassan.blogspot.co.uk PS> "test$( 'string' )"
test string


#### Importing a DLL

Given a $dll_file_path, use the following command:  Add-Type -Path$dll_file_path
# OR
Add-Type -AssemblyName "System.Web" # for .NET DLL's.


#### Instantiating an Object

##### Instantiating an existing class

Any object within the System namespace in mscorelib.dll can be instantiated without explicitly providing the "System" namespace before it:


$date = New-Object DateTime(2009, 01, 01)  However, for any class outside of the System namespace, you have to provide the full namespace: $date = New-Object System.Text.StringBuilder(2009, 01, 01)
# The first argument to New-Object is a string and the rest of the arguments don't have to be in brackets:
# $date = New-Object "System.Text.StringBuilder" 2009, 01, 01  Since the first argument (the type) is a string, we can use store the namespace of the type in a string: $text_ns = "System.Text"
# $date = New-Object "$text_ns.StringBuilder" 2009, 01, 01

##### Creating a Hashtable using @{} sytax

To create an hashtable you can use the @{} syntax:


$tahir = @{ Name = 'Tahir'; BlogUrl = 'tahirhassan.blogspot.co.uk' } #OR$tahir = @{ '"Name' = 'Tahir'; 'BlogUrl' = 'tahirhassan.blogspot.co.uk' } # quotes around the keys


Notice that we use a semi-colon and not a comma to separate the key-value pairs.

##### Creating a PSObject with a set of properties:

To do this we use the New-Object 'PSObject' –Property [HashTable]:


$tahir = New-Object 'PSObject' -Property @{ 'Name' = 'Tahir'; 'BlogUrl' = 'tahirhassan.blogspot.co.uk' }  #### Creating an Array To create a basic array, you can merely list the elements: $my_arr = 1, 2, 3, 4, 5


But using this syntax you cannot create an empty list. A better syntax is using the @(...):


# same as above
$my_arr = @(1, 2, 3, 4, 5) # empty array$my_arr = @()
# concatenating two arrays using the + operator.
$my_arr = @(1, 2, 3) + @(4, 5)  To access one of the elements you use the square bracket notation: $my_arr[3]


#### Creating an ArrayList

To create an arraylist, you can cast an array (as above) to an ArrayList:


$arraylist = [System.Collections.ArrayList]$array


#### Calling Static Methods

To call a static method, you need to provide the full type name, which includes the namespace. (there is no way round this):


[System.Int32]::MaxValue # can use [int] instead here.


#### Getting Help on commands

To get help on a command, say Get-Process, type the following:


Get-Help Get-Process


#### Executing a Cmdlet

In PowerShell, merely typing the cmdlet name will execute it:


Get-Process


Notice that in the above code, we do not use brackets after it e.g. Get-Process(), however the cmdlet is still being executed. When assigning the output notice that

In order to take the first element of this, we need to put brackets around Get-Process and use the square bracket notation:


(Get-Process)[0]


PowerTab is an extension of the PowerShell tab expansion feature. It can be found at CodePlex - PowerTab.

#### Viewing information using Out-GridView

Piping information to Out-GridView cmdlet will show the information in a GUI:


dir | Out-GridView


#### Relational Operations

Inspired by Relational shell programming.

##### Sorting

To order or sort by, use the Sort-Object, aliased as sort:


dir | Sort-Object name

Alternatively we can pass a function to sort (aka "selector"):

dir | Sort-Object {$_.Name.SubString(0, 1)}  ##### Selecting (aka "Projecting") ###### Naively Using Select-Object When naively selecting using the Select-Object:  dir | Select-Object 'Name', 'Mode'  What happens is that a PSCustomObject is created with the properties selected. ###### Using Select-Object with a Selector Apparently, Select-Object is not designed to work with with a selector:  PS> dir | Select-Object {$_.Name}

$_.Name ------- Folder1 Folder2 PS> (dir | Select-Object {$_.Name})[0].'$_.Name' Folder1  Basically, it returns PSCustomObject's with a$_.Name property. We instead wanted it to return the Name property only. To to this we can still call Select-Object but with the -ExpandProperty option:


PS> dir | Select-Object -ExpandProperty 'Name'
Folder1
Folder2
PS> (dir | Select-Object -ExpandProperty 'Name')[0]
Folder1


However this still does not solve the problem of when we want to pass in a selector. For this, we use the Foreach-Object.

###### Using Foreach-Object for true Selection

To use Foreach-Object (or it's alias %) we pass in a selector:


PS> dir | Foreach-Object { $_.Name } Folder1 Folder2  ##### Select Top N Elements To get the first N elements using Powershell  dir | Select-Object -First 3  We can also skip a certain number of elements:  dir | Select-Object -Skip 2  #### Getting Current Path Use Get-Location:  Get-Location  #### Executing a string using Call Operator (&) Use & as follows:  & "C:\Program Files\Notepad++\notepad++.exe" "my_file.txt"  #### Customizing Prompt to only show last Directory Name Stick the following into your$profile file (create it if it does not exist:


function prompt {
$loc_path = (Get-Location).Path;$cur_dir = $loc_path.SubString($loc_path.LastIndexOf('\') + 1);
$prompt_str = if ($cur_dir -eq "") { $loc_path } else {$cur_dir };
return "PS: \$prompt_str> ";
}


If it complains that it does not have the permissions to run the start up script then execute the following:


Set-ExecutionPolicy Unrestricted -Force


#### Setting Up Alias's for Commonly used Apps

Use Set-Alias to do this: