<< 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, 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, 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, initialize

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

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 one-liners

–B–

background color, get

(Get-Host ).UI.RawUI.BackgroundColor

background color, set

$a = (Get-Host).UI.RawUI

$a.BackgroundColor = "DarkGreen"

There aren’t too many choices

[Enum]::GetValues([ConsoleColor])

only lists 16 color choices

–C–

can’t load a script

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

case statement - see switch

can’t run scripts - see scripts disabled

certs, list

Get-ChildItem -Recurse Cert: | ft

clipboard, send output of a command to

simply append your command with "| clip"

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

compress a file - see zip a file

concatenate - +

contains, does a variable contain a substring?

if ($DisplayName -match "departed")

copy files from one directory to another

$destination = "D:\xml\"
$location = "D:\Client Portal\"
function processCopy

{

  $files = Get-ChildItem -Path:$location
  foreach($file in $files)
   {
   $path = $file.FullName
  if($file.Name -ne "copy.ps1"){
   Copy-Item -Path:$path -Destination:$destination -Force -Confirm:$false
   Write-Host "Item" $file.Name " has been sucessfully copied to" $destination
   }
   if($file.Attributes -eq "Directory")
   {
    copyFile $file $destination
   }
  }
}

function copyFile($directory, $target)
{
  $target += $directory.Name
  $files = Get-ChildItem -Path:$directory.FullName
  foreach($file in $files)
  {
  $path = $file.FullName
  if($file.Name -ne "copy.ps1"){
  Copy-Item -Path:$path -Destination:$target -Force -Confirm:$false
  Write-Host "Item" $file.Name " has been sucessfully copied to" $target
  }

  if($file.Attributes -eq "Directory")

  copyFile $file $target
  }
  }

 
function Pause ($Message="Press any key to continue...")
{
  Write-Host -NoNewLine $Message
  $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  Write-Host ""
}
#main
processCopy
Pause

Count how many files in a directory, excluding "bin" and "obj" files & directories

(gci "D:\VisualStudio\GID_CRM" -exclude bin, obj -Recurse).Count

–D–

date of files, determine

ls d:\filemaker -rec | foreach {$_.creationtime -lt "02/25/2013"}

date of most recent file in a directory

$latest = Get-ChildItem -Path $backedUpDirectoryPath | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$latest.name
$latest.LastWriteTime

directory, loop through

$sourceDirectory= "D:\somedirectory"
ls $sourceDirectory -rec | foreach {
  $filename = $_.Name
  $length = $_.length
  $creationtime = $_.creationtime
  $DirectoryName = $_.Directory.Name
  Write-Host $i $filename ", " $DirectoryName ", " $length ", " $creationtime
  $i++
}

delete file

Remove-Item $a[$i] -recurse -force

directory, delete certain subdirectories and everything underneath them

gci $workingDirectory -include bin, obj, Upload -Recurse -Force | Remove-Item -Recurse -Force

To just get directories without all the files

In Powershell 3.0, it is simpler:

dir -Directory #List only directories
dir -File #List only files

Or to limit to just 2 directories deep:

dir -Directory .\*\*

In PowerShell 2, to just get directories (with grouping):

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }

Or to limit to just 2 directories deep:

Get-ChildItem .\*\* | ?{ $_.PSIsContainer }

To get a raw list of directories, without the grouping:

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

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

$variable

disabled scripts - see scripts disabled

–E–

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

elapsed time

$diff = New-TimeSpan $latest.LastWriteTime $StartDate

$howLongAgo = "$($diff.days)d $($diff.hours)h $($diff.minutes)m"

email

$smtpFrom ="fromEmail@yourDomain"

$smtpTo ="toEmail@yourDomain"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpTo

$message.Subject = $messageSubject

$message.IsBodyHTML = $true

$message.Body = $body

$smtpServer = "yourTenant-com01ec.mail.protection.outlook.com"

$smtp = new-object Net.Mail.SmtpClient($smtpServer)

$credentials = new-object system.net.networkcredential("whosSending@yourDomain","TopSecret")

$smtp.credentials=$credentials.getCredential($smtpServer,"25","basic")

$smtp.Send($message)

This does not work all the time

send-mailmessage -to "user@mydomain.com" `
  -from "user@mydomain.com" `
  -subject "sample subject line" `
  -smtpServer mymailserver.mydomain.com `
  -body 'test body'

not only does it not work, putting in a "try-catch" block doesn't give you an error; it errors out right away when you first try to run.

email user info

get-msoluser -userprincipalname test@yourdomain.com | fl

emails, count of from one user for a day

[Int ] $intRec = 0
Get-TransportService | `
  Get-MessageTrackingLog -ResultSize Unlimited -Start "4/09/2015" -End "4/10/2015" `
  -Recipients "someuser@yourdomain.com" -EventID DELIVER | `
  ForEach { $intRec++ }
Write-Host "E-mails received:", $intRec

equal - -eq()

error, expand

$error | Format-List -Force

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

event log -

Get-EventLog -LogName 'Application' -ErrorAction SilentlyContinue |
    Select TimeWritten, Message, EventID |
    Where-Object -FilterScript {$_.EventID -eq 3054 -and $_.TimeWritten -ge '12/8/14 9 am'} |
    Export-Csv EventID3054_recent.csv

exit from for loop -

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

–F–

file, folder exist?

if (Test-Path C:\Scripts)
{
 if (Test-Path C:\Scripts\Test.txt)
 {
  "Folder and file exist"
 }
 else
 {
  "Folder exists, file doesn't"
 }
}
else
{
 "Folder does not exist"
}

file, read into array

$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)"

}

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

–G–

greater than - -gt()

greater than or equal - -ge()

gridview - | Out-GridView or | ogv

groups for a department

# this just sets up the file to be in a directory we know we have permission: "My Documents"
$outputfile = "yourOutPutFile.txt"
$mytemp= [environment]::getfolderpath("mydocuments")
$outputfile= $mytemp + "\" + $outputfile
 
# this one, multi-piped line does everything we want
Get-ADUser -filter {mail -like "*yourdomain.com"} -Properties DisplayName, mail, memberof | % {
  $email = $_.mail
  $Name = $_.DisplayName
  $_.memberof | Get-ADGroup | Select @{N="User";E={$Name}},@{N="email";E={$email}}, Name
} | Export-Csv $outputfile -nti

–H–

hash, clear

$a.Clear()

–I–

IP addresses for IIS, list in order

To get the list sorted by IP:

Import-Module WebAdministration
$sites = Get-ChildItem IIS:\sites
$bindings = $sites | foreach-object { $_.Bindings} | foreach-object {$_.Collection} | foreach-object {$_.BindingInformation}
$bindings | Sort-Object

–J–

–K–

–L–

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.

log into SQL Server database, can't using non-integrated security - make sure your connection string includes, ";Trusted_Connection = yes"

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

ForEach-Object 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

loop, escape - break (all by itself)

–M–

My Documents location

$mydocs = [environment]::getfolderpath("mydocuments")

change directory to my documents

$dir = [environment]::getfolderpath("mydocuments")

cd $dir

–N–

not - -not()

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–

or - -or

output results of a command to clipboard

simply append your command with "| clip"

–P–

password for SQL Server database doesn't work using non-integrated security - make sure your connection string includes, ";Trusted_Connection = yes"

PowerGui

profile location - $profile

To create a whole new profile (it checks first to make sure we don't already have one):

if (!(test-path $profile)) {new-item -type file -path $profile -force}

Prompt, change - helpful to include this in scripts that connect to other servers

function global:prompt{

    $promptString = "UK " + $(Get-Location) + ">"

    write-host -NoNewLine -ForegroundColor Cyan $promptString

    return " "

}

#change prompt

prompt

That "global:" up top is pretty important

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–

–S–

Scheduling PowerShell Scripts (in Server 2008)

In the "Action" tab, for the "Start a program", need to have "powershell" for the "Program/script" and the file location for the "Add arguments (optional)". If you're attempting to run some commands - like New-Object IO.FileSystemWatcher then you must precede the file name with "-NoExit . " (including the dot).

Scripts disabled -

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

Services

Find if you don't know the exact name but have some idea of the name. For example: you know the service has something to do with the word, "profile":

get-service | Where-Object {$_.DisplayName -like "*profile*"} | ft

sort -

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

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

These, of course, are just a couple examples of many possible such.

SQL Server database, can't connect to using non-integrated security - make sure your connection string includes, ";Trusted_Connection = yes"

SQL, execute - see also here and here for arrays

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$ConnectionString = "Server=someserver;Database=somedb;User Id=someuser;Password=yourpwd"
$SqlConnection.ConnectionString = $ConnectionString
try
{
$sqlConnection.Open()
}
catch [System.Data.SqlClient.SqlException]
{
Write-Host "Problem connecting to database"
write-host $_.Exception.ToString()
#write-host $_.Exception.state
exit
}
$sqlCommand = $sqlConnection.CreateCommand()
$SQLStr = "select * from table"
$sqlCommand.CommandText = $SQLStr
$dr = $sqlCommand.ExecuteReader()
$SqlConnection.Close()
$DataSet.Tables[0]

if you then want to loop through the recordset returned:

while ($dr.Read())
{
  $firstFieldValue = $dr.GetValue(0)
  $secondFieldValue = $dr.GetValue(1)
}

This is all well and good for select statements.  But for update and inserts, need something else:

$updateSQL = "update table set somefield = 3"
$sqlCommand.CommandText = $updateSQL
$sqlCommand.ExecuteNonQuery()

string, find just one

$s = "New York City"

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

string, find if any of several match

$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

Select-String -Path d:\inetpub\somedirectory\*.aspx -pattern somestring

string, replace

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

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

–T–

task scheduler, run a powershell script in

in the "Actions" tab, in the "Start a program" area, put in "powershell"

In the "Add arguments" area, put in "-ExecutionPolicy Bypass D:\path\YourPowerShellScript.ps1"

If you see, "This task requires that the user account specified has Log on as batch job rights" the user must be able to do the following

  1. Start -> Run
  2. Type in secpol.msc /s
  3. Select "Local Policies" in MSC snap in
  4. Select "User Rights Assignment"
  5. Right click on "Log on as batch job" and select Properties
  6. Click "Add User or Group", and include the relevant user.

tenant, which one am I on?

Get-MsolAccountSku

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

timestamp - see filter timestamp example

–U–

user (Office 365), does he exist?

$User = Get-MsolUser -UserPrincipalName $target -ErrorAction SilentlyContinue -ErrorVariable errorVariable
If ($User -ne $Null)
{
    write-host "$target exists" -Foregroundcolor green 
} Else
{
    write-host "$target does not exist" -Foregroundcolor yellow
}

user (Office 365), restore when UserPrincipalName has a domain not accepted by the tenant

Restore-MsolUser -UserPrincipalName someuser@baddomain.com -AutoReconcileProxyConflicts -NewUserPrincipalName someuser@tenantname.onmicrosoft.com

user info (email) - Office 365

individual - use either UPN:

Get-MsolUser -userprincipalname test@yourdomain.com | fl

or objectID:

Get-MsolUser -ObjectId 81701046-cb37-439b-90ce-2afd9630af7d | fl

everyone:

Get-MsolUser | Sort-Object DisplayName,UserPrincipalName

userPrincipalName

change:

Set-MsolUserPrincipalName -UserPrincipalName "becky.smith@yourcompany.onmicrosoft.com" -NewUserPrincipalName"becky.smith@yourcompany.com"

–V–

version

PS C:\> $Host.Version
Major Minor Build Revision
----- ----- ----- --------
2     0     -1    -1

means you have PowerShell version 2

Get-Host just shows you the version of the host (i.e. of Console.Exe). To see the version of PowerShell, use the built in variable

PS C:\> $PSVersionTable

shows

Name                      Value
----                      -----
PSVersion                 4.0
WSManStackVersion         3.0
SerializationVersion      1.1.0.1
CLRVersion                4.0.30319.34014
BuildVersion              6.3.9600.16394
PSCompatibleVersions      {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2

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–

Where am I? As in: which tenant am I on? - See which tenant am I on (right below)

Which tenant am I on? - the closest I can find is the command to list all the licenses that a tenant has available:

Get-MsolAccountSku

This will return a list of license SKUs. Embedded in each AccountSkuId will be the tenant name before the ":". Pretty hokey.

Windows Services - see Services

–X–

–Y–

–Z–

zip a file

[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )

$src_folder = "D:\project"

$destfile = "D:\project.zip"

$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal

$includeBaseDir = $false

[System.IO.Compression.ZipFile]::CreateFromDirectory($src_folder, $destfile, $compressionLevel, $includeBaseDir)

–No's–