Useful PowerShell functions and snippets

This post contains a few (short) useful PowerShell functions and snippets, that you can include in projects and/or your profile, and some which showcase some peculiar solutions to problems in PowerShell.


This one is for use in your profile, so you can see in Alt-Tab which Powershell console is running with which user.
I just put this as the first line in the $profile file:

$host.ui.RawUI.WindowTitle = "PowerShell - $env:USERDOMAIN\$env:USERNAME"
#Alternative, but with an external executable: 
#$host.ui.RawUI.WindowTitle = "PowerShell - $(whoami)"

UPDATE: By combining the above line with the Is-Elevated function (shown below), formats and a condition, you can also add information indicating if the PowerShell console is running as administrator (This also shows a way to use a boolean condition to return a conditional string from an array).
Of course, the Is-Elevated function needs to be defined first, so this shows the entire construct:

function Is-Elevated {
 $prp = new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
 $prp.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}

$host.ui.RawUI.WindowTitle = "PowerShell - {0}\{1}{2}" -f $env:USERDOMAIN,$env:USERNAME,@(""," - as Admin")[(Is-Elevated)]

Some people consider the construction with the array ugly or unreadable.
This is how this construction then works in this example:

$host.ui.RawUI.WindowTitle = "PowerShell - {0}\{1}{2}" -f $env:USERDOMAIN,$env:USERNAME,$(if (Is-Elevated) {" - as Admin"})

This is a simple function to search the English text about_* help files in the documentation in the PowerShell install folder:

function Search-Help {
    $pshelp = "$pshome\en-US\about_*.txt"
    select-string -path $pshelp -pattern $args[0]
}

A shortcut to view a help article in an external window:

function Get-HelpW {
    Get-Help $args[0] -showwindow
}

Investigating the methods and the properties of objects:

function Get-Methods ($obj) {
    $obj | Get-Member -MemberType Method
}
function Get-Properties ($obj) {
    $obj | Get-Member -MemberType Property
}

Get the static methods of the Path object:

function Get-PathMethods {
    [System.IO.Path] | Get-Member -Static
}

Listing the values of all properties of an object:

function Get-PropertyValues($obj) {
  $obj | Format-List *
}

Getting the full type name of the last exception, so you can use it in a Catch [] statement:

function Get-LastExceptionType() {
    $Error[0].exception.GetType().fullname
}

Checking if a script process is running elevated (as Administrator):

function Is-Elevated {
    $prp = new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
    $prp.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}

For when you cannot remember how to call the garbage collector:

function Collect-Garbage {
    [System.GC]::Collect()
}

Get a datetime value formatted as a sortable string (Defaults to current time):

function Get-QDate {
    param(
        [parameter()]
        [DateTime]$dt = ([DateTime]::Now)   # or (Get-Date)
    )
    "{0:yyyyMMdd-HHmmss}" -f $dt
    #Alternatives:
    # Get-Date $dt -format yyyyMMdd-HHmmss
    # "{o:u}" -f $dt
}

Some random Date expressions:

$(Get-Date).AddDays(-16930).AddHours(-11).AddMinutes(-36)
(Get-Date) - (New-TimeSpan -Day 16930 -Hour 11 -Minute 36)

Dynamically convert a hash table containing hash tables to an array of objects:

function hash2obj($data) {
    $result = @();  
    foreach($row in $data) {
        $obj = new-object PSObject
        foreach($key in $row.keys) {
            $obj | add-member -membertype NoteProperty -name $key -value $row[$key]
        }
        $result += $obj
    }
    return $result;
}


Excel open workbook example:

$excel = new-object -com excel.application
$wb = $excel.workbooks.open("c:\t\t.xlsx")

Windows registry modification example.
This particular code modifies an item in the registry key for Windows 10’s Update default reboot behavior, so it will not reboot if a user is still logged on (This code was tested with PS version 5.1.14393.206).
The value is not set if the registry key does not exist.

[string]$key = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
[string]$item = "NoAutoRebootWithLoggedOnUsers"
[int32]$value = 1
if (test-path $key) {
    set-itemproperty $key -name $item -value $value
}

Windows Forms sample/snippet to quickly display a ListBox and two buttons (OK & Cancel) in a modal dialog-style window, and to display the selected choice afterwards:

[CmdletBinding()]
param()

# Helper function
function Get-FormControl {
    param(
        [parameter(Mandatory=$true)]
        [object]$objControl,
        [parameter(Mandatory=$true)]
        [object]$objDim,
        [parameter()]
        [string]$sText
    )

    if ($objDim.x -ne $null) {
        $objControl.Location = New-Object System.Drawing.Size($objDim.x, $objDim.y)
    }
    $objControl.Size = New-Object System.Drawing.Size($objDim.w, $objDim.h)
    if ($sText -ne '' -and $sText -ne $null) {
        $objControl.Text = $sText
    }
    return $objControl
}

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$oWshell = New-Object -ComObject Wscript.Shell

$winlayout = [PSCustomObject]@{
    form        = [PSCustomObject]@{w = 300; h = 400};
    label       = [PSCustomObject]@{x = 10;  y = 8;   w = 280; h = 15};
    listbox     = [PSCustomObject]@{x = 10;  y = 27;  w = 270; h = 315};
    butOK       = [PSCustomObject]@{x = 75;  y = 343; w = 75;  h = 23};
    butCancel   = [PSCustomObject]@{x = 150; y = 343; w = 75;  h = 23};
}

#Create the Form
$objForm = Get-FormControl (New-Object System.Windows.Forms.Form) $winlayout.form "Window Title"
$objForm.FormBorderStyle = 'FixedDialog'; $objForm.MaximizeBox = $false
$objForm.StartPosition = "CenterScreen"
$objForm.Topmost = $True

#Add a label
$objForm.Controls.Add((Get-FormControl (New-Object System.Windows.Forms.Label) $winlayout.label "Label for the ListBox"))

#Add the buttons
$OKButton = Get-FormControl (New-Object System.Windows.Forms.Button) $winlayout.butOK "&OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$objForm.Controls.Add($OKButton)
$objForm.AcceptButton = $OKButton

$CancelButton = Get-FormControl (New-Object System.Windows.Forms.Button) $winlayout.butCancel "&Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$objForm.Controls.Add($CancelButton)
$objForm.CancelButton = $CancelButton

#Add the ListBox
$objListBox = Get-FormControl (New-Object System.Windows.Forms.ListBox) $winlayout.listbox ''
$objListBox.Height = $winlayout.listbox.h     #For ListBixes, Height needs to be set, next to Size
"Option 1", "Option 2", "Option 3" | foreach {
    [void] $objListBox.Items.Add($_)
}
$objListBox.SelectedIndex = 0     # Leave this out if you want no option preselected
$objForm.Controls.Add($objListBox)
#$objListBox.Select()             # Enable this if you want the control to be preselected

while($true) {
    $result = $objForm.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::CANCEL) {
        break
    }
    if ($objListBox.SelectedIndex -ge 0) {
        #$objListBox.SelectedIndex
        $objListBox.SelectedItem
        break
    }
    [void] $oWshell.Popup("Please select a valid option",0,"Popup Title",0x40)
}
Share