Useful Powershell stuff

Group objects into batches of X items with a constructed property, credit to Dave Wyatt:

$bigList = 1..1000
$counter = [pscustomobject] @{ Value = 0 }
$groupSize = 100
$groups = $bigList | Group-Object -Property { [math]::Floor($counter.Value++ / $groupSize) }

—–
Use “PipelineVariable” to pass data down the pipeline rather than using a foreach:

Get-ADUser <username> -PipelineVariable user -Properties memberof |
    Select-Object -ExpandProperty memberof |
        Select-Object @{ n = ‘Name’; e = { $user.Name }}, @{ n = ‘MemberOf’ ; e = { $PSItem -replace ‘CN=|,(OU|CN)=.+’ }}


Also if a cmdlet does not support -pipelineVariable you can pass it to Where-Object

Get-Mailbox -ResultSize Unlimited | Where-Object {$true} -PipelineVariable mbx | whatever

—–
Convert a list of strings into a single line string delimited by quotes and separated by commas, suitable for using in a “IN” statement in SQL/SOQL

$ids is a list of ID strings
$idsString = $ids -replace “(\w+)",‘‘‘$1’''  -join ‘,‘
or if it’s one large string separated by line breaks (e.g. copied from a spreadsheet):
$idsString = ($ids -replace “(\w+)",‘‘‘$1’'').Split(“n") -join ','<br /><br />-----<br />Print a line<br />'_' * 100<br /><br />Prevent null references, incorrect syntax usage, unnamed variables:<br />Set-StrictMode -Version Latest<br /><br />Creating a new instance of a .net framework object<br />New-Object TypeName "System.Diagnostics.Stopwatch"<br />Or more simply, New-Object System.Diagnostics.Stopwatch<br />Because it's a string, don't use the type name in angle brackets like PS normally would<br /><br />To view absolutely everything that's happening internally in the powershell pipeline for a particular scriptblock:<br />Trace-Command -Name * -Expression {Get-Service winrm | Restart-Service} -PSHost<br /><br />Add a calculated property to a list of objects, along with all the other properties:<br />&nbsp; &nbsp; Select *,@{Name="ExtraField"; Expression={$_.SomeValue+1}}, @{Name="Whatever"; Expression={"Some string"}}<br /><br />Get a list of drives, including network drives and their UNC paths (like with "net use"):<br />&nbsp; &nbsp; Get-WmiObject -Class win32_logicaldisk<br /><br />Get previous session history with "get-history"<br />Run a previous command without pushing up 1000 times with "invoke-history"<br /><br />csi = C# interactive (custom alias)<br /><br />Formatting:<br />get a list of every property and value for an object:<br />&nbsp; &nbsp; $whatever | Format-List<br />Prevent output from truncating:<br />&nbsp; &nbsp; Format-Table -AutoSize -Wrap<br /><br />Redirection:<br />&amp; { blah } 1 &gt; $null&nbsp; &nbsp; - suppress standard output from executing "blah". <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection" target="_blank">More info</a><br />$var = &amp; Do-Stuff *&gt;&amp;1&nbsp; - redirect all output to standard output and store that in $var<br />&amp; { whatever } 2&gt;$null 3&gt;$null - redirect error and warning streams<br /><br />Output:<br />get-content .\somefile -Wait&nbsp; - tail-like behaviour, displays additions to the file<br />get-content | more&nbsp; - allows paging of output<br /><br />Getting a count of duplicated things:<br />$whatever | group FieldToGroup | where Count -gt 1 | sort Count -Descending | select Name, Count<br /><br />set-clipboard (scb) - sets the contents of the clipboard to whatever is pasted in.&nbsp; Useful with sls for non-powershell commands that output text that you have to use in another command<br /><br />Delimiters<br />t - tab

When using delimiters with “Import-Csv -Delimiter”, make sure not to surround them with quotes

cd env:    gets environment vars
get-psprovider    lists providers
get-psdrive    lists drives
get-module -listavailable    lists all available modules

hashtable of variables for passing in parameters
$parameters = @{
    ‘param1’ = $value1
    ‘param2’ = $value2
}

Run-SomeCmdlet @parameters     <- notice the @ symbol, not $

write-verbose lines in a function only write if a -verbose flag was provided to the function

@($a) forces $a to be in an array

use regexes with “where” with the “match” operator:
    gci | where name -match ‘\d{2}‘

rename properties for a select:
        ps | select @{Name='Title’;Exp={$_.ProcessName}}

select-string (alias: sls)
    very useful for selecting strings from a whole bunch of string-based output
    works like grep in linux
        ipconfig | sls subnet

To use IIS stuff:
    Import-Module WebAdministration
open IIS drive and navigate to a website:
    cd IIS:<br />    cd sites\sitename

Get a list of every module
    Get-Module -ListAvailable
Find a module based on name
    Get-Module *web*
Find all commands in a module
    Get-Command -Module WebAdministration

get current item members:
    gi . | gm
recycle an app pool by navigating to it
    cd IIS:\AppPools\somewebsite
    (gi .).Recycle()
or also in one line:
    (gi IIS:\AppPools\somewebsite).Recycle()

ii (invoke-item)
    performs the default action on an item, e.g. opens a file using a program

-join operator, joins strings together
    when used first (unary), joins without delimiting
        -join (“asdf”, “qwer”) #outputs asdfqwer
    when used as a binary operator, allows a delimiter
        (“asdf”, “qwer”) -join ‘-’ #outputs asdf-qwer

-replace operator, using regex to replace strings
    replace pairs of html tags with <small>:
        $foo = $foo -replace ‘<(/)?\w+>', ‘<$1small>‘

searching application event log for a particular guid:
    Get-EventLog -logname application | where {$_.Message -ilike “*6CD27361-D038-E611-9B7F-005056956605*") } | select message