<< A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

–A–

and

-and

array, compare - differences

$a1 =@(1,2,3)

$b1=@(1,2,3,4)

(Compare-Object $a1 $b1 ).InputObject

returns

4

array, compare - SideIndicator

$a1 =@(1,2,3,4,5,8)

$b1=@(1,2,3,4,5,6)

Compare-Object $a1 $b1

returns

InputObject SideIndicator
----------- -------------
  6 =>
  8 <=

array, convert into from object - see object, convert into array

array, create from string with delimited values

$recipients = $addresses -split ";"

array, declare so increasing the number of elements is not restricted

[System.Collections.ArrayList]$array = @()

array, duplicate elements - find

$a = @(1,2,3,1,2)
$ht = @{}
$a | foreach {$ht["$_"] += 1}
$ht.keys | where {$ht["$_"] -gt 1} | % {Write-Host "Duplicate element found $_"}

array, find string as a member of

$array = 1,2,5,8,3,4,5

to use:

$array.Contains(2)

above returns True

$array.Contains(12)

above returns False

array, find elements of an array somewhere in a string

We're looking for a user that might belong to

the line below beginning with “if($null” has the test

$arrayTenants = ("UK","US","Germany")
#declare a hash of tenants with their respective qualifying OUs as elements
$O365Tenant = @{}
$O365Tenant["US"] = ("one","two","three")
$O365Tenant["UK" = ("four","five","six")
$O365Tenant["Germany"] = ("seven")
Get-ADUser -Filter 'name -like "*"' | ForEach-Object {
    $distinguishedName = $_.distinguishedName
    ForEach ($tenantName in $arrayTenants)
    {
        if($null -ne ($O365Tenant[$tenantName] | ? { $distinguishedName -match $_ }))
        {
           "$tenantName found"
        }
    }
}

see here for more

array, import from text file - see text file, import into an object, record for each field in a file, parse, CSV, import into an object

array index, find which inside of foreach loop

foreach ($item in $array) {
    $array.IndexOf($item)
}

array, initialize

$myArray = @("a","b","c","d","e","f","g","h")
$myArray = "a","b","c","d","e","f","g","h"

array, loop through

create array and then display one at a time

$upn = @("user1@yourDomain.com", "user2@yourDomain.com", "user3@yourDomain.com")
$upn | %{"$_"}

to also list the indices:

$upn | %{"$($upn.IndexOf($_)) $_"}

array, methods available (static) - display

[array] | gm -s | select name, definition | ft -a

This is basically a "get help" command for the PowerShell array function

array of hashes, populate - see hash, array of, populate

array of objects - convert to array of strings

put all our OU names into an array

$arrayOUs = Get-ADObject -Filter {ObjectClass -eq 'organizationalunit'} -Properties CanonicalName | Select-Object -Property Name
# convert the array of objects into an array of strings
$strArrayOUs = $arrayOUs | ForEach {"$($_.Name)"}

array, print contents of

the trick is the built-in ofs variable

$proxyAddresses = $user.proxyAddresses
$ofs = '; ' # render $proxyAddresses array printable - separated by "; "
"$($proxyAddresses.Count) useful proxyAddresses: $proxyAddresses" # prints out array count & array contents separated by "; "

array one-liners

array, read into from text file - see text file, import into an object, record for each field in a file, parse, CSV, import into an object

–B–

break - see also continue, exit, return

terminates execution of a loop or switch statement and hands over control to next statement after it

This does not work like this if the loop in question is part of a piped foreach ("%") statement. If you try that, the dang code just dies right here and never proceeds to the next statement!

–C–

can’t load or run a script - see also scripts disabled

File C:\Scripts\ListDir.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details. At line:1 char:14 + .\ListDir.ps1 <<<< + CategoryInfo : NotSpecified: (:) [], PSSecurityException + FullyQualifiedErrorId : RuntimeException

From an elevated prompt:

Set-ExecutionPolicy Unrestricted

or better (restricted to only current user):

Set-ExecutionPolicy Unrestricted -Scope CurrentUser

Sometimes the command above won't work. It will likely complain about some more specific scope overriding your attempt.

Set-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope. Due to the override, your shell will retain its current effective execution policy of AllSigned.

To find out more, list all the different scopes:

Get-ExecutionPolicy -List

might return something like this:

Scope         ExecutionPolicy
-----         ---------------
MachinePolicy Undefined
UserPolicy    Undefined
Process       Restricted
CurrentUser   Undefined
LocalMachine  Unrestricted

More specific scopes like Process override less specific scopes like CurrentUser. So we need to change the more inclusive Process scope. Try this:

Set-ExecutionPolicy Bypass -Scope Process -Confirm

You may wonder: why not just set this Process scope to Unrestricted as well? But the system may not allow it. But setting it to Bypass instead will probably be allowed.

case statement - see switch

can’t run scripts - see scripts disabled, can’t load or run a script

clipboard, send output of a command to

simply append your command with "| clip"

color of Write-Host command - see also Write-Color

Write-Host "green color" -foreground "green"

multiple colors on one line

Write-Host "Green " -ForegroundColor Green -NoNewline; Write-Host "Red "-ForegroundColor Red -NoNewline; Write-Host "Yellow " -ForegroundColor Yellow

colors, show available

[enum]::GetValues([System.ConsoleColor]) | Foreach-Object {Write-Host $_ -ForegroundColor $_}

colors, multiple in one line - see Write-Color

command history

shows each command, sequence and duration for the current session - most recent up top

Get-History | select id, CommandLine, StartExecutionTime, EndExecutionTime, @{n="duration";e={$_.EndExecutionTime - $_.StartExecutionTime}} | sort id -Descending | ogv

comment out a line - use "#".  For a block of comments, "<#" at beginning of block followed by "#>" at end of block

concatenate - +

continue - see also break, exit, return

skip the current execution of the loop and to return the execution to the top of the innermost loop

contains, does a variable contain a substring?

if ($DisplayName -match "departed")

CSV, import into an object - see also text file, read into object, record for each field in a file, parse

$dir = [environment]::getfolderpath("mydocuments")
$docName = "$($dir)\someFile.csv"
$csv = Import-Csv $docName
$i=0; $count = $csv.Count
$result = @()
foreach ($item in $csv)
{
    $i++; $percentTxt = ($i/$count).ToString("P")
    Write-Host "$i of $($count) ($percentTxt): Name = $($item.Name) and email = $($item.Email)" -ForegroundColor Green
    $result += New-Object -TypeName PSObject -Property @{
        Name = $item.Name
        Email = $item.Email}
}
$result = $result | sort Name | select Name, Email
$result | ogv

CSV, import special characters

Even though a CSV may look like it has special characters, doesn't mean those are actually stored as unicode that gets processed the right way.

$dir = [environment]::getfolderpath("mydocuments")
$originalFileName = "$($dir)/input.csv"
$convertedFileName = "$($dir)/$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss'))inputConverted.csv"
Get-Content $originalFileName | Out-File $convertedFileName -Encoding UTF8
Remove-Item $convertedFileName -recurse -force
$csv = Import-Csv $convertedFileName
Foreach ($item in $csv){Write-Host "$($item.Name) - $($item."email address")" -ForegroundColor "green"}

Had the original "input.csv" file had what appeared to be special characters and you merely "Import-Csv" on it and looped through using "foreach" without first "Get-Content" piped to "Out-File" with "-Encoding UTF8", you likely would have only seen unprintable character resembling a solid diamond with a question mark in it for each of those special characters.

Notice that we immediately delete the intermdiate $convertedFileNamefile because we don't want it left around to clutter things up once we're done with it.

–D–

date, convert string to

$myDate = [DateTime]"Jul-16"

date, include in file name - see timestamp, include in file name

digitally signed, ps1 file won't run

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

display value of a variable - simply put the variable in its own line. No write-host necessary:

$variable

disabled scripts - see scripts disabled

duplicate elements in an array, find - see array, duplicate elements - find

duration of last command - see time it took to run most recent command

–E–

edit scripts - powershell ISE (included with Windows 7, 8)

elapsed time - see time elapsed

environment variables

list all

gci env:* | sort-object name

domain

$env:UserDomain

computer name

$env:ComputerName

path

$env:Path -split(";") | sort $_

user name

$env:UserName

or

whoami

equal - -eq()

error, expand

$error | Format-List -Force

error when running script - see can't load a script

even number, test for

1..20 | % {if ($_ % 2 -eq 0 ) {"$_ is even"}}

execution policy - see scripts disabled

exit - see also break, continue, return

terminates the current execution session altogether. It also closes the console window and may or may not close ISE.

exit from for loop -

if $thing -eq 'some_condition')
{
  break
}

–F–

file, read into array – see text file, import into an object

$file = "someFile.htm"
$myDocs = [environment]::GetFolderPath("MyDocuments")
$file = $myDocs + "\" + $file
$fileContent = Get-Content $file
for ($i= 0; $i -lt $fileContent.length; $i++){
   $fileContent[$i]
}

This is all well and good. But what if we really want an array of hashes? The following works good for CSVs

$csv= Import-Csv $inputfile
foreach($item in $csv)
{
   "$($item.UserPrincipalName) -  $($item.DisplayName)"
}

file name, include timestamp in - see timestamp, include in file name

filter timestamp example

filter timestamp {"$(Get-Date -Format G): $_"}

write-output "hello world" | timestamp

find whether elements of an array can be found anywhere in a string - see array, can elements of an array can be found anywhere in a string

foreign characters - see also special characters, CSV, import special characters

If a command exports users whose names contain foreign characters into a CVS file, those foreign characters will be replaced with a ?. To preserve those foreign characters, use Export-Csv $outputfile -Encoding UTF8

Get-Content $file | Out-File $fileUTF8 -NoTypeInformation -Encoding UTF8

function, return more than one value – see Returning multiple values from a PowerShell function

function, invoke function residing outside file

Occasionally you may want to keep functionality in a file and maybe even directory outside of the script you're running rather than have to store those functions inside the script.

$directoryWithFunctions = "\\deathstar.galaxyfarfaraway.com\Infrastructure\"
. "$($directoryWithFunctions)DestroyPlanetLaser.ps1"
cd $directoryWithFunctions

Or the other way around:

cd $directoryWithFunctions
. ".$($directoryWithFunctions)DestroyPlanetLaser.ps1"

–G–

greater than

-gt

greater than or equal

-ge

gridview - | Out-GridView or | ogv

group by

Get-User | Group RecipientTypeDetails

–H–

hash, clear

$a.Clear()

hash, declare

$guestUsers = @{}

hash, array of, populate

$guestUsers = @(
    @{email = 'bob.smith@yourDomain.com'; DisplayName = "Bob Smith"}
    @{email = 'jim.jones@yourDomain.com'; DisplayName = "Jim Jones"}
    @{email = 'sally.hayes@yourDomain.com'; DisplayName = "Sally Hayes"}
)

history of commands - see Command History

how long did the last command take to run? See time it took to run most recent command, Command History

–I–

-in operator – see also -notin operator

"orange" -in "orange","apple" # True

import text file into array - see text file, import into an object, record for each field in a file, parse, CSV, import into an object

'Install-Module' is not recognized

Start with Get-PackageProvider

Get-PackageProvider

Hopefully, you ought to get at least 3 rows, one of which ought to be PowerShellGet. If Get-PackageProvider isn't recognized, try Install-PackageProvider

Install-PackageProvider -Name NuGet -Force

invoke function residing outside file – see function, invoke function residing outside file

–J–

join members of an array together separated by character(s)

$groups = @("US Users","Staff","Big building")

$allGroups = ($replace | % {$groups}) -join ','

–K–

–L–

last command, how long did it take to run? - see time it took to run most recent command

less than - -lt()

less than or equal - -le()

line continuation - use the “grave accent” (`) mark.

Get-ChildItem -Recurse `
-Filter *.jpg `
| Select LastWriteTime

However, this is only ever necessary in such cases as shown above. Usually you get automatic line continuation when a command cannot syntactically be complete at that point. This includes starting a new pipeline element:

Get-ChildItem |
Select Name,Length

Similar to the | a comma will also work in some contexts.

strings (in all varieties) may also extend beyond a single line:

'foo
bar'

They include the line breaks within the string, then.

line number,return

Function Get-CurrentLine {
    $Myinvocation.ScriptlineNumber
}
 
Get-CurrentLine
$null
Get-CurrentLine

loop, percent progress through - see percent progress through a loop

loop - several types

For - read content of a file as in

$file = "someFile.htm"
$myDocs = [environment]::GetFolderPath("MyDocuments")
$file = $myDocs + "\" + $file
$fileContent = Get-Content $file
for ($i = 0; $i -lt $fileContent.length; $i++){
   $fileContent[$i]
}

ForEach - for “normal” arrays - see also array, loop through

ForEach-Object (or "%") for objects - you need to have the “{” on the same line right after the “ForEach-Object” or you’ll get prompted for:

cmdlet ForEach-Object at command pipeline position 2

Supply values for the following parameters:

Process[0]:

unlike the other flavors of “ForEach” and “While” which expect the “{” to be on the next line.

While - loop through the contents of a file or database query/table

continue - see also break, exit, return

loop, escape - break (all by itself) - see break, continue, exit, return

Keep in mind that this does not work like you'd expect if the loop in question is part of a piped foreach ("%") statement. If you try that, the dang thing just dies and never proceeds to the next statement after the loop!

lower case - see also proper case

append ".ToLower" to string. For example:

$Username = "$($FirstName.Substring(0,1))$LastName".ToLower()

takes the first letter of $FirstName variable and appends to $LastName and then puts whole thing lower case.

–M–

Module install attempt fails

If you attempt to run some command like

Install-PackageProvider -Name "PowerShellGet"

or

Get-PSRepository

or

Get-InstalledModule

and get some error like this

PacketManagement\Find-Package: Unable to find module providers (PowerShellGet) At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModules.psm1:1397 char:3

look under Documents\WindowsPowerShell folder for a "Modules" folder under that and then delete or rename that "Modules" folder to something like "ModulesOld" and try again. It should recreate that "Modules" folder. And now things might work better.

Modules installed

Gets installed modules on a computer:

Get-InstalledModule

Gets the modules that have been imported or that can be imported into the current session:

Get-Module

What's available:

Get-Module -ListAvailable

update a module:

Update-Module -Name someModule -Verbose

Sometimes you must know where a module is installed. Especially if you need to uninstall or import.

$AzureInstalled = Get-InstalledModule | Where-Object {$_.Name -like 'Azure*'}
$AzureInstalled | select Name, InstalledLocation

Module providers

You may try to run a command like

Find-Module *ms*

and get an error

PacketManagement\Find-Package: Unable to find module providers (PowerShellGet) At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModules.psm1:1397 char:3

or some such directory path, file & line number. Before you go chasing down that directory to make sure the module exists, run this command first to find out what Package Providers you have

Get-PackageProvider

You should get a list of package providers. If the one you want (PowerShellGet in this case) is missing, then try:

Install-PackageProvider -Name "PowerShellGet"

if this fails, see Module install attempt fails

Modulo operator (remainder in division)

if $i below is 10, 20, 30, etc., the if statement below will be true

if ($i % 10 -eq 0) {$i}

–N–

not

-not()

-notin operator – see also -in operator

"orange" -notin "orange","apple" # False

null, assign

sometimes you can assign the $null variable. Other times you must use the -clear operator.

null, check if string is null

if ([string]::IsNullOrEmpty($mystring) {Write-Host "string is NULL or EMPTY"}
else {Write-Host "string has a value"}

null, check if property is null when filtering

Normally, you can simply filter on someProperty -ne $null. But when trying to filter on some commands like Get-AdUser, problems because PowerShell doesn't recognize what the $null variable is in that context. So instead, filter on -notlike "*".

Get-AdUser -filter (msExchHideFromAddressLists -notlike "*")} -Properties $Properties

–O–

object, convert into array

Let's say you already have an object $objResult with many fields, one of whose fields is called "Source Workstation". To convert this particular field to an array $PCs:

$PCs = $objResult.("Source Workstation")

To get rid of dupes:

$PCs = $PCs | select -Unique

odd number, test for

1..20 | % {if ($_ % 2 -eq 1 ) {"$_ is odd"}}

or

-or

output results of a command to clipboard

simply append your command with "| clip"

–P–

percent progress through a loop

$employees = Get-Msoluser -All
$i=0; $count = $employees.Count
$employeesWithMailboxes = @()
foreach ($employee in $employees) {
    $i++; $percentTxt = ($i/$count).ToString("P")
    $displayName = $employee.DisplayName
    $messagePrefix = "$i of $($count) ($percentTxt): $displayName"
    Write-Host "$messagePrefix now" -ForegroundColor Green
}

PowerGui

PowerShell version - see also Windows version

Use the built in variable

$PSVersionTable

shows

Name                           Value
----                           -----
PSVersion                      5.1.17763.134
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.134
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

or

$PSVersionTable.psversion

gives version detail in table format

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      17763  134

Get-Host just shows you the version of the host (i.e. of Console.Exe or Visual Studio Code Host).

Name             : Visual Studio Code Host
Version          : 1.10.2
InstanceId       : 7f3dd862-f8ce-49a2-b420-b44ccebc0053
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.EditorServices.EditorServicesPSHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

Or $Host.Version will zero into more detailed version info in a table format.

$Host.Version
Major Minor Build Revision
----- ----- ----- --------
1     10    2     -1

means you have Visual Studio Code Host version 1

progress through loop, percent - see percent progress through a loop

proper case

$words = 'wAr aNd pEaCe'

$TextInfo = (Get-Culture).TextInfo
$TextInfo.ToTitleCase($words)

if all caps:

$words = 'WAR AND PEACE'

$TextInfo.ToTitleCase($words)

$TextInfo.ToTitleCase($words.ToLower())

property name has spaces - see spaces in property name

properties of object, see all

This example gets all properties of a folder:

Get-ItemProperty \\fs.jiminy.org\songs | Format-List -Property *

or

Get-ItemProperty \\fs.jiminy.org\songs | Get-Member | ? {$_.memberType -eq "Property"}

properties - sometimes you can just add Select-Object. But usually you need to add a Select-Object As in:

Get-MsolUser -All | Select-Object UserPrincipalName, isLicensed, immutableID

–Q–

When to Quote in PowerShell

–R–

read text file into array - see text file, import into an object, record for each field in a file, parse, CSV, import into an object

record for each field in a file, parse

Instead of getting one record with each field delimited by something like a comma as you would in a CSV, occasionally you get a separate record for each file. In the case below, we have two separate fields - “DisplayName” and “Department” - and each is on its own record. We need to gather these two fields together and put them all together in one record.

$dir = [environment]::getfolderpath("mydocuments")
$docName = "$($dir)/ticket1519133.txt"
$fileContents = Get-Content -Path $docName
$i=0; $count = $fileContents.Count
$fieldCount = 2
$result = @()
foreach ($line in $fileContents)
{
    $i++; $percentTxt = ($i/$count).ToString("P")
    if ($i % $fieldCount -eq 1) {
        $DisplayName = $line
    } else {
        $j = [math]::floor([decimal]($i/$fieldCount))
        $jcount = [math]::floor($count/$fieldCount)
        Write-Host "$j of $($jcount) ($percentTxt): $line" -ForegroundColor Green
        $result += New-Object -TypeName PSObject -Property @{
            "DisplayName" = $DisplayName
            "Department" = $line
        }
    }
}
$result = $result | select DisplayName, Department
$result | ogv

remainder (as in division) - see modulo

replace

PowerShell Replace Method And Operator: Syntax, Examples or How to Use PowerShell Replace to Replace Text [Examples]

Method - case sensitive

("Sad to see you").Replace("S","Gl")

you can also “chain” these together

("Sad to see you go").Replace("S","Gl").Replace("you go","you're back!")

Operator - not case sensitive

("Sad to see you") -Replace("S","Gl")

return - see also break, continue, exit

terminates execution of the current function and passes control to the statement immediately after the function call

return more than one value from a function – see function, return more than one value

–S–

Scripts disabled - see also can’t load or run a script

To see current policy:

Get-ExecutionPolicy

To change current policy:

Set-ExecutionPolicy RemoteSigned

But what if you get this?

Set-ExecutionPolicy : Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied.
At line:1 char:1
+ Set-ExecutionPolicy RemoteSigned
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   + CategoryInfo          : NotSpecified: (:) [Set-ExecutionPolicy], UnauthorizedAccessException
   + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand

Answer: run PowerShell as an administrator

spaces in property name - enclose with quotes as in

$_."IP Address"

spaces in string, trim – see white space, trim

special characters - see also CSV, import special characters, foreign characters

special characters, replace

[char[]]$replace = '!@#$%^&*(){}[]":;,<>/|\+=`~ '''
$regex = ($replace | % {[regex]::Escape($_)})-join '|'
cd 'D:\test
Get-ChildItem -recurse |
  ForEach {
    if ($_.Name -match $RegEx){
      Ren $_.Fullname -NewName $($_.Name -replace $RegEx, '_') -whatif
    }
  }
if ($DisplayName -match "departed")

or

[char[]]$replace = '!@#$%^&*(){}[]":;,<>/|\+=`~ '''

$regex = ($replace | % {[regex]::Escape($_)}) -join '|'

Get-ChildItem -recurse | Where-Object { $_.Name -match $RegEx} | Rename-Item -NewName {$_.Name -replace $RegEx, '_'} -whatif

sort -

Get-EventLog system -newest 5 | Sort-Object eventid

Get-MsolUser -All | Sort-Object -property UserPrincipalName

If you want to sort stuff descending, add the -Descending argument

Get-SPOSite | select Url, StorageUsageCurrent, WebsCount | sort StorageUsageCurrent -Descending | ft

If you want to sort stuff descending and ascending, need to do things a little differently

Get-SPOSite | select Url, StorageUsageCurrent | sort @{expression="StorageUsageCurrent";Descending=$true},@{expression="Url";Ascending=$true} | ft

string, how many instances - see Counting the number of occurrences of a string or file in PowerShell

"OU=Pumpkin Patch,DC=farms,DC=Dogpatch,DC=gov" -split ",DC=" | measure | select -exp count

If you expect these strings to always be in the middle somewhere, then subtract 1. Because the example above returns 4 because that's how many substrings result from the split - even though there are only 3 instances of the string we're searching.

string, find just one

$s = "New York City"

"New","Old" | %{ if ($s.contains($_)) { "$s contains $_" }}

string, find if any of several match - see also string, how many instances

$ignoreDirectories = @("SYSVOL","#recycle","SysStates","LogsConfig")
if(Select-String -InputObject $filename -pattern $ignoreDirectories)
{
  Write-Host "ignore" $filename
}

“-match” also works but is usually used to find match in an array

string, can elements of an array can be found anywhere in - see array, can elements of an array can be found anywhere in a string

string, find files that contain in a directory

if you're already in the directory you want to search:

Get-ChildItem -recurse | Select-String -pattern "something went wrong" | group path | select name

if you're not already in the directory you want to search, you can try this. You might get permission complaints, though:

Select-String -Path C:\inetpub\wwwroot -pattern "something went wrong"

string, find whether it is in an array - array, find string as a member of

string, replace

$a = $a -replace "one", "two"

substring - see also string, how many instances

append ".Substring(start position, number of characters)" to string. For example:

$Username = "$($FirstName.Substring(0,1))$LastName".ToLower()

takes the first letter of $FirstName variable and appends to $LastName and then puts whole thing lower case.

switch statement - same as the “case” statement in other languages - see here

–T–

term 'xx' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. (Exchange)

for example:

get-mailbox -ResultSize Unlimited

returns:

get-mailbox : The term 'get-mailbox' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ get-mailbox -ResultSize Unlimited
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (get-mailbox:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

need to run:

add-pssnapin *exchange* -erroraction SilentlyContinue

text file, import into an object - see also CSV, import into an object, record for each field in a file, parse

$dir = [environment]::getfolderpath("mydocuments")
$docName = "$($dir)\textToImport.txt"
$fileContents = Get-Content -Path $docName
$i=0; $count = $fileContents.Count
$result = @()
foreach($line in $fileContents)
{
    $i++; $percentTxt = ($i/$count).ToString("P")
    Write-Host "$i of $($count) ($percentTxt): $line" -ForegroundColor Green
    $result += New-Object -TypeName PSObject -Property @{
        line = $line}
}
$result | ogv

time elapsed

the best way to see how long recent commands took to run that I've found so far:

Get-History | select id, CommandLine, StartExecutionTime, EndExecutionTime, @{n="duration";e={$_.EndExecutionTime - $_.StartExecutionTime}} | sort id -Descending | ogv

loop example

$startTime = $(Get-Date)
Write-Host "Elapsed:00:00:00"
$NoEvent = $true
While ($NoEvent)
{
  Start-Sleep 1
  $elapsedTime = New-TimeSpan $startTime $(Get-Date)
  Write-Host "Elapsed:$($elapsedTime.ToString("hh\:mm\:ss"))"
  #Handle event
  if(event){$NoEvent = $false}
}

or use the .NET Stopwatch class

$Time = [System.Diagnostics.Stopwatch]::StartNew()
$NoEvent = $true
while ($NoEvent) {
    $CurrentTime = $Time.Elapsed
    Write-Host $([string]::Format("`rTime: {0:d2}:{1:d2}:{2:d2}", $CurrentTime.hours, $CurrentTime.minutes, $CurrentTime.seconds)) -nonewline
    Sleep 1
    #Handle event
    if(event){$NoEvent = $false}
}

time it took to run most recent command - see also Command History

(Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime

how long it took each of the previous 10 commands to run

for ($i = -1; $i -gt -10; $i--){
    $duration = (Get-History)[$i].EndExecutionTime - (Get-History)[$i].StartExecutionTime
    "duration for event $($i): $duration"
 }

timestamp - see filter timestamp example

timestamp, convert to string

(Get-Date).ToString("MM/dd/yyyy hh:mm:ss tt")

timestamp, include in file name

$outFile = "baseFileName_{0:yyyyMMdd-HHmm}.csv" -f (Get-Date)

or if you don't want to mess with a variable and want to send to the My Documents folder

Get-AdUser | Export-Csv -Path "$([environment]::getfolderpath("mydocuments"))\fileBaseName$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv" -NoTypeInformation -Encoding UTF8

title case - see proper case

tools

ISESteroids - add-on for the Windows PowerShell ISE editor

top 5 - add following to any command: | Select-Object -First 5

trim – see also white space, trim

" first last ".Trim()

try/catch - will suppress system error message but instead keep going and show error of your choice (and highlight just the pertinent part of the error message with back color if you have Write-Color module installed)

$dir = [environment]::getfolderpath("mydocuments")
$docName = "$($dir)/my.csv"
$csv = Import-Csv $docName
foreach ($item in $csv)
{
    try {
        $user = Get-MsolUser -UserPrincipalName $item.UserPrincipalName
        Write-Host "$($item.DisplayName) / $($item.UserPrincipalName) found" -ForegroundColor Green
    }
    catch {
        Write-Color -T "$($item.DisplayName) / $($item.UserPrincipalName) ", "not found!" -C Blue, Red -B Black, DarkYellow
    }
}

I've never been able to get try/catch to work properly with Get-Mailbox failure - see Get-Mailbox failure for work-around

–U–

upper case - see also proper case

append ".ToUpper" to string

user name environment variable - see environment variables

–V–

variable name has spaces - see spaces in property name

version, install latest

winget install Microsoft.PowerShell

if that fails:

Invoke-Expression "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"

As far as I can tell, this doesn't allow you to specify a version. Whether you want it or not, it's 7. But you can cancel it before it finishes.

version, which installed?

PowerShell

Windows

Visual Studio, install

Install-Script Install-VSCode -Scope CurrentUser; Install-VSCode.ps1

Visual Studio, shell setting, default - go to File → Preferences → Settings

Integrated Terminal

// Place your settings in this file to overwrite default and user settings.
{
     "terminal.integrated.shell.windows": "\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"
}

or 64-bit PowerShell

     "terminal.integrated.shell.windows": "C:\\WINDOWS\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.ex"

check if 64-bit:

[Environment]::is64bitProcess

should return True

–W–

white space, trim

# Expected to remove leading and trailing two spaces.
("  Test  ").Trim()
#Expected to remove the leading two spaces and carriage return and newline characters.
("  Test`r`n").Trim()
# Expected to remove the leading two spaces and trailing Unicode Next Line character.
("  Test Test $([Char]0x0085)").Trim()

Who am I?

whoami

Write-Color

# Install from Powershell Gallery https://www.powershellgallery.com/packages/PSWriteColor
Install-Module -Name PSWriteColor
Import-Module PSWriteColor

tabs and vertical space

Write-Color -Text "This is text in Green ",
"followed by red ",
"and then we have Magenta... ",
"isn't it fun? ",
"Here goes DarkCyan" -Color Green, Red, Magenta, White, DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1

with background colors and aliases

Write-Color -T "My text", " is ", "all colorful" -C Yellow, Red, Green -B Green, Green, Yellow

–X–

xml, parse

If you include a line like this in your DNS:

        _dmarc	3600	 IN 	TXT	v=DMARC1; pct=100; p=none; rua=mailto:someUser@yourDomain.com

you'll get XML records mailed to you from various email providers such as yahoo & google. The code below will get some of the columns; not all columns fetched for simplicity's sake.

$dir = [environment]::getfolderpath("mydocuments")
$fileNameOnly = "google.com!youdDomain.com!1556064000!1556150399.xml"
$fileName = "$dir\$fileNameOnly"
[xml]$xml = Get-Content -Path $fileName
$xml_row = $xml.SelectNodes("//row")
$objResult = @()
foreach ($row in $xml_row) {
    $rowRecord = $row | select @{n='sourceIP';e={$_.source_IP}},@{n='DKIM';e={$_.policy_evaluated.dkim}},@{n='spf';e={$_.policy_evaluated.spf}}
    $objResult += $rowRecord
}
$objResult | ogv

–Y–

–Z–

–No's–