SHIFT

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


Sidebar

Recently Changed Pages:

View All Pages


View All Tags


LinkedIn




WIKI Disclaimer: As with most other things on the Internet, the content on this wiki is not supported. It was contributed by me and is published “as is”. It has worked for me, and might work for you.
Also note that any view or statement expressed anywhere on this site are strictly mine and not the opinions or views of my employer.


Pages with comments

View All Comments

cheatsheet

Cheat Sheet

An overview of all sorts of commands and script usage.
Best practices and Styling

Most Used

PowerShell History

View history of powershell commands and invoke them using “r #”
Get-History
<# Output #>
r 1


See all saved commands in vscode
code (Get-PSReadLineOption).HistorySavePath

PowerShell Scripts

If statement
if (($alllogs -eq "True") -AND ($result)){
    Write-Host "Both statements are true"
}elseif (($buildreason -eq "IndividualCI") -or ($buildreason -eq "BatchedCI") -or ($buildreason -eq "PullRequest")){
    Write-Host "At least one of the statements is true"
}else {
    Write-Host "None of the statements is true"
}

Windows Service Management

Stop Windows Service
  1. # Stop the service while checking the state for x² seconds and kill it if that doesn't work
  2. Write-Host "Stopping Service: $servicename; Status: Initiating"
  3. $sleeper = 1
  4. while (((Get-Service -Name "$servicename").Status -ne "Stopped") -AND ($sleeper -lt 128)){
  5. if ($sleeper -eq 1){
  6. Stop-Service -Name "$servicename"
  7. } elseif ($sleeper -eq 32){
  8. Stop-Service -Name "$servicename" -Force -NoWait
  9. } elseif ($sleeper -eq 64){
  10. # Try to kill the process now
  11. $servicepid = (Get-CimInstance win32_service -Filter "Name = '$servicename'").ProcessId
  12. try{
  13. Stop-Process -id $servicepid -Force
  14. }catch{
  15. Throw "Stopping Service: $servicename; Stopping process: $servicepid; Status: Failed; Error: $($_.Exception.Message)"
  16. }
  17. }
  18. if ($alllogs -eq "True"){Write-Host "Stopping Service: $servicename; Sleeptime: $sleeper seconds"}
  19. Start-Sleep -Seconds $sleeper
  20. $sleeper = $sleeper * 2
  21. }


Restart all Windows Services
get-service -name green* -ComputerName appprd02 | Restart-Service -Verbose


Start all stopped Windows Services
Get-Service -Name green* -ComputerName appprd01,appprd02,appprd03,appacc01,appacc02,apptst01,apptst02,appdev01,appdev02 | Where-Object {$_.Status -eq 'Stopped'} | Start-Service -Verbose
Get-Service | where {($_.Status -eq 'Stopped') -and ($_.name -like 'Green*') -and ($_.StartType -eq 'Automatic')} | Start-Service

Note: -ComputerName only works in PS 5

Install Windows Service depends on Powershell version
if ($($PSVersionTable.PSVersion).Major -eq 7){
    New-Service -Name $serviceName -BinaryPathName $binaryAppExecutable -StartupType "AutomaticDelayedStart" -Credential $appuserCredentials
}else {
    New-Service -Name $serviceName -BinaryPathName $binaryAppExecutable -StartupType "Automatic" -Credential $appuserCredentials
    sc.exe config $serviceName start= delayed-auto
}

Note: PS 5 does not understand the startuptype AutomaticDelayedStart

Delete Windows Service
sc.exe delete windows.service

Note: In cmd you can use sc, in powershell sc is an alias for set-content, so you need to use sc.exe

Windows Certificates

View cert info
certutil -v -dump <path to cert>


Open Current User Certificate store:
certmgr.msc


Open Local Machine Certificate store:
certlm.msc

Active Directory

Count all users in all departments
Get-ADUser -SearchBase "OU=Users,DC=GetShifting,DC=local" -filter * -Properties name,department,enabled  | where {$_.enabled -eq "true"} | group department | select name, count


All enabled users that have never logged
Get-ADUser -Filter {(lastlogondate -notlike "*" -AND enabled -eq "True")} -SearchBase "OU=Users,DC=GetShifting,DC=local"


All enabled users that have not logged on for more than 90 days
$90Days = (get-date).adddays(-90)
Get-ADUser -Filter {(lastlogondate -le $90days -AND enabled -eq "True")} -SearchBase "OU=Users,DC=GetShifting,DC=local"


All servers
Get-ADComputer -Filter {(operatingSystem -like "*windows*Server*")}

Note: Does not select Windows 2000 Servers.

Select servers on properties
Get-ADComputer -filter {(description -like "*financial*" -AND name -like "SQL*")} -Properties * | select name, description

PowerShell Dates

# Dates
$timestamp = Get-Date -format "yyyyMMdd-HH.mm" # 20211011-14.27
$readdate = Get-Date -format "d MMM yyyy" # 11 Oct 2021
$weekdate = Get-Date -uformat %V # Week number # 41
$monthdate = Get-Date -format "MMMM-yyyy" # May-2021

Networking

Reverse loopup with ping
ping -a 10.10.10.10


NSlookup with default nameserver
nslookup servername


NSlookup with non-default nameserver ns01
nslookup servername ns01


Remote desktop console
mstsc.exe /v:servername /admin 


Test connection
Test-NetConnection -InformationLevel "Detailed" -Computername $host

PowerShell Input and Output

Try Catch Error Finally with LineNumber for troubleshooting
  1. function Get-ScriptLineNumber {
  2. return $MyInvocation.ScriptLineNumber }
  3. try{
  4. Write-Host "Do something that you want to catch the error of"
  5. }catch{
  6. # Catch the error
  7. Write-Host "Full Error: $_"
  8. # Or error out after all
  9. Throw "Failed on: $actionname; Status: Failed; Line: $(Get-ScriptLineNumber); Error: $($_.Exception.Message)"
  10. }finally {
  11. <#Do this after the try block regardless of whether an exception occurred or not#>
  12. # For example, clean up remote ps sessions
  13. }


Default powershell function - adds variables and parameters from azure devops yaml pipeline
  1. <#
  2. .SYNOPSIS
  3. Default Function Example
  4.  
  5. .DESCRIPTION
  6. Describes the function
  7. Define the input
  8. Log the input
  9. Start the function
  10.  
  11. .EXAMPLE
  12.  
  13. DefaultPSFunction -site $site -webserver $webserver -environment ${{ parameters.environment }} -alllogs ${{ parameters.alllogs }}
  14.  
  15. .NOTES
  16. General notes & Links
  17.  
  18. https://docs.microsoft.com/en-us/powershell/module/iisadministration/?view=windowsserver2022-ps
  19.  
  20. #>
  21. function DefaultPSFunction{
  22. param (
  23. [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$site,
  24. [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$webserver,
  25. [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$environment,
  26. [string] $alllogs
  27. )
  28. if ($alllogs -eq "True"){
  29. write-host "`n##[section]Function: $($MyInvocation.MyCommand).`n"
  30. Write-Output "Input: site: $site; webserver: $webserver; environment: $environment"
  31. }
  32. }


Enable logging of script
  1. ### Script Variables ###
  2. $scriptname = [System.IO.Path]::GetFilenameWithoutExtension($MyInvocation.MyCommand.Path.ToString())
  3. $scriptlocation = Split-Path $myinvocation.mycommand.path
  4. $date = (Get-Date).ToString('yyyyMMdd-HHmm')
  5.  
  6. ### Start transcript for full logging capabilities ###
  7. start-transcript -path "$scriptlocation\$scriptname-$date-logtranscript.txt"
  8.  
  9. ### Stop transcript
  10. Stop-transcript


Script output and Write-Host options
  1. # Inside a function use return or write-output
  2. return "value"
  3. Write-Output $value
  4. # Output an object without adding it to the function output
  5. Write-Host "color" -ForegroundColor Red -BackgroundColor green -noNewLine
  6. $object | Out-Host


Input password
$password = Read-Host "Enter password" -asSecureString


Use padright to fill a line with one symbol
Write-Host ''.PadRight(78, '=')
# Or with a variable
$wide = 32
Write-Host ''.PadRight($wide, '=')

Output in Azure DevOps

Logging output
# Logging output in azure devops
##[group]Beginning of a group - white 
##[warning]Warning message - orange 
##[error]Error message - red 
##[section]Start of a section - green 
##[debug]Debug text - purple 
##[command]Command-line being run - blue 
##[endgroup] - green 
Write-Host "`n##[section]Function: $($MyInvocation.MyCommand).`n"


Log error or warning
Write-Host "##vso[task.logissue type=error]Something went very wrong."
Write-Host "##vso[task.logissue type=warning]Found something that could be a problem."


Generate extra output if debug mode is set
if ($env:SYSTEM_DEBUG -eq "True"){$headers | Out-Host}

Remote PowerShell

Set variables
  1. $AdminCredentials = Get-Credential
  2. $remotePort = 5986
  3. $pso = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
  4. $Culture = "en-US"
  5. $pso.Culture = $Culture
  6. $pso.UICulture = $Culture
  7. $sessionParams = @{}
  8. $sessionParams.Add('UseSSL', $true)
  9. $sessionParams.Add('Port', $remotePort)
  10. $sessionParams.Add('Credential', $AdminCredentials)


Start session to restart computer
$session = New-PSSession -ComputerName webserverdmz.domain -EnableNetworkAccess -SessionOption $pso @sessionParams
Invoke-Command -Session $session -ScriptBlock {Restart-Computer}
Remove-PSSession $session

PowerShell Variables

Set system (environment) variable
$env:var="value"


Get all system (environment) variables, sorted by name
get-childitem -path env:* | Sort Name


Variables in function
Declare a variable with script scope to use it in a function
$script:orgUrl = "https://dev.azure.com/getshiftingcom"
$script:apiversion = "api-version=6.0"
function SetBuildTag {
  # Load Azure DevOps API settings
  AzureDevOpsAPISettings
  foreach ($tag in $tags){
      $tagurl = "$orgUrl/$env:System_Teamproject/_apis/build/builds/$env:BUILD_BUILDID/tags/$($tag)?$apiversion"
  }
}

Variables in Azure DevOps

Pipeline variable in yaml - without PowerShell
variables:
  - name: BuildConfiguration
    value: 'Release'
- task: DotNetCoreCLI@2
  displayName: "Build Solutions"
  inputs:
    command: 'build'
    projects: '**/*.sln'
    arguments: '--no-restore --configuration $(BuildConfiguration)'


Pipeline parameter in yaml
if ( "${{ parameters.alllogs }}" -eq "True" ){write-Host "Parameter from pipeline"}


System variable in yaml
Variables can be used like system environment varriables

if (Test-Path "$env:Build_SourcesDirectory\$env:Build_Repository_Name\appsettings.Development.json"){Write-Host "System / Environment Variable"}
$sites = get-childitem -path env:* | Where-Object {$_.name -like "*-SiteName"} | Select-Object -ExpandProperty value # Added through Variable Group


Variables can also be used like pipeline variables

get-childitem $(Pipeline.Workspace) 
$dbserver = "$(serverDb)" + "." + "$(dnsZone)" # from Azure App Configuration


Variables in PS scriptfile
$adserver = $env:adServer + "." + $env:domain # from Azure App Configuration
$projects = Get-ChildItem -Path "$env:Build_SourcesDirectory\$env:Build_Repository_Name\deploy\" -Directory | Select-Object Name

Docker Containers

Show running container
docker ps
# or
docker container ls


Show all containers
docker ps -a


docker stop/start/restart containers
docker stop container_id
# default grace time = 10
docker stop --time=5 container_id 
docker start container_id
# Restart apache container by name
docker container restart httpd_web


Get docker container info
docker inspect container_id


Get docker container compose info
docker inspect container_id | grep com.docker.compose


Work in a container
docker exec -it container_id /bin/bash

Linux Bash

grep file without empty lines and comments
grep -v '^\s*$\|^\s*\#' postgresql.conf

PowerShell

PowerShell Function Template

See here for guidelines.
function Use-AzureDevOpsApi{ #Use Get-Verb for a list of approved verbs
    <#
    .SYNOPSIS
        Short description
 
    .DESCRIPTION
        Long description
 
    .PARAMETER Pat
        Explain the parameter Pat. Repeat for additional parameters.
 
    .OUTPUTS
        Explain the powershell output, if any
 
    .EXAMPLE
        Pipeline example:
        - task: PowerShell@2
          displayName: "Use Default SystemAccessToken" 
          env:
            SYSTEM_ACCESSTOKEN: $(System.AccessToken) 
          inputs:
            pwsh: true
            targetType: 'inline'
            script: |
                # Load Azure DevOps API settings
                Use-AzureDevOpsApi
 
        Script example:
        Use-AzureDevOpsApi -Pat $Pat
 
    .LINK
        System access token: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken
 
    .NOTES
        Author : Sjoerd Hooft
        Version: 2022-08-03 
 
    #>
    [CmdletBinding()]
    param (
        [Parameter()]
        [ValidateLength(52,52)] # See for more paramater validation https://poshcode.gitbook.io/powershell-practice-and-style/style-guide/function-structure 
        [ValidateSet("dev", "tst", "acc")]
        [string]
        $Pat
    )
 
    BEGIN {
        if ($alllogs -eq "True"){
            Write-Host "`n##[section]Function: $($MyInvocation.MyCommand).`n"
            Write-Host "Input: Package: $package; Feed: $feed; View: $view; environment: $environment"
        }
        # Collect information
    }
 
    PROCESS {
        # Do stuff
    }
 
    END {
        # Cleanup
    }
}

PowerShell Modules

Check Azure powershell module depending on PS version
  1. Write-Host "Check required PowerShell Modules `n"
  2. # The "new" PS module for Azure requires PowerShell 7
  3. if ($($PSVersionTable.PSVersion).Major -eq 7){
  4. if (Get-Module -ListAvailable -Name AZ) {
  5. Write-Host "PowerShell module Azure exists"
  6. } else {
  7. Write-Host "PowerShell module Azure does not exist. Start installation. "
  8. Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
  9. }
  10. }else{
  11. Throw "Powershell needs to be version 7"
  12. }


PowerShell DNS Module
if (Get-Module -ListAvailable -Name DnsServer) {
    Write-Host "PowerShell module DnsServer exists"
} else {
    Write-Host "Module DNSServer does not exist. Starting installation"
    Import-Module ServerManager
    Add-WindowsFeature -Name "RSAT-DNS-Server"
}


PowerShell AD Module
# Because ActiveDirectory is a 5.1 module you need to add -All 
if (Get-Module -ListAvailable -All -Name ActiveDirectory) {
    Write-Host "PowerShell module ActiveDirectory exists"
} else {
    Write-Host "Module ActiveDirectory does not exist. Starting installation"
    Import-Module ServerManager
    Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature
}


PowerShell Pester module, remove shipped version and install latest version (Needs PS 7)
  1. if (Get-Module -ListAvailable -Name Pester) {
  2. # Check for version 3.4 and if available remove it
  3. Get-Module -ListAvailable -Name Pester
  4. if (((((Get-Module -ListAvailable -Name Pester).Version).Major) -eq 3) -AND ((((Get-Module -ListAvailable -Name Pester).Version).Minor) -eq 4)) {
  5. Write-Host "PowerShell Module Pester is version 3.4 which is shipped along with Win10/Windows 2016. Start removal:"
  6. $module = "C:\Program Files\WindowsPowerShell\Modules\Pester"
  7. takeown /F $module /A /R
  8. icacls $module /reset
  9. icacls $module /grant "*S-1-5-32-544:F" /inheritance:d /T
  10. Remove-Item -Path $module -Recurse -Force -Confirm:$false
  11. }
  12. # Verifieer of Pester al aanwezig met minimaal versie 5
  13. if ((((Get-Module -ListAvailable -Name Pester).Version).Major) -ne 5) {
  14. Write-Host "PowerShell module Pester is not up to date"
  15. Install-Module -Name Pester -Force -Scope CurrentUser
  16. }else{
  17. Write-Host "PowerShell Module Pester is available with minimal version of 5:"
  18. Get-Module -ListAvailable -Name Pester
  19. }
  20. } else {
  21. Write-Host "PowerShell module Pester does not exist. Start installation. "
  22. Install-Module -Name Pester -Force -Scope CurrentUser
  23. }


IIS Administration Module, install extra version, see the version and the available commandlets. Note that this needs to be done in PowerShell 5 Administrative Shell
Install-Module -Name IISAdministration -Scope AllUsers -Force #Installs latest version next to it (1.1.0.0)
Import-Module IISAdministration -RequiredVersion 1.1.0.0
$mod = Get-Module -Name IISAdministration
$mod.Version
$mod.ExportedCmdlets | Format-Table


Import PS Module
Import-Module Pester


Get commands within a module
Get-Command -module Pester


Remove / Unload a PowerShell module
Remove-Module Pester

PowerShell ForEach

With custom PS Object and export to csv
  1. $myCol = @()
  2. foreach ($vm in (get-vmhost esxprd101.intranet | get-vm )){
  3. $VMInfo = "" | Select-Object VMName,VMHostName,NICCount
  4. $VMInfo.VMName = $vmview.Name
  5. $VMInfo.VMHostName = $vmview.Guest.HostName
  6. $VMInfo.NICCount = $vmview.Guest.Net.Count
  7. $myCol += $VMInfo
  8. }
  9. $myCol |Export-csv -NoTypeInformation $csvfile

PowerShell Comparison

Overview
# logical and comparison 
# -and, -or, -not , ! : Connect expressions 
# -eq, -ne : Equal, not equal 
# -gt / -lt, -ge / -le : Greater/less than, greater or equal / less or equal 
# -replace 
# -match / -notmatch : Regular expression match 
# -like / -notlike : wilcard matching 
# -contains / -notcontains : check for value in array: $array -contains $value
# -in / -notin : reverse syntax from contains: $value in $array 

PowerShell Location

Change directory (alias cd)
Set-Location c:\


Change directory and back
PS C:\Users\sjoer> Push-Location c:\
PS C:\> Pop-Location
PS C:\Users\sjoer>

Azure PowerShell

NOTE: Module AZ only works in PS 7


TLS version
# Set TLS version to use TLS 1.2 
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


Login and context
Connect-AzAccount
Get-AzContext -ListAvailable
Set-AzContext -Name $dtapEnvironment -Subscription $azureSubscriptionName


Get TenantId
$tenantId = (Get-AzContext).Tenant.Id


Get secret from KeyVault
$adadminpass = (Get-AzKeyVaultSecret -VaultName kv-operations-global -Name "adAdminPass").SecretValue


Set secret to KeyVault
$userpasswordsecure = ConvertTo-SecureString -String $userpassword -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName kv-operations-global -Name $username -SecretValue $userpasswordsecure

Windows Processes

Get all processes
$processes = Get-CimInstance -ClassName Win32_Process | Select-Object ProcessName,ProcessId,CommandLine,Path | sort processid


Kill a process
try{
    $processid = (Get-CimInstance win32_process -Filter "Name = 'mmc.exe'").ProcessId
    if ($null -ne $processid){
        Stop-Process -id $processid -Force
    }
}catch{
    Write-Host "Error killing mmc: $_"
}

Windows CommandLine

Windows System

Collect uptime, patches, windows version and more
systeminfo 

System Variables

Set an environment variable until the end of the current command prompt session
set AWS_DEFAULT_REGION eu-west-1


Set an environment variable in both the current command prompt session and all command prompt sessions that you create after running the command
setx AWS_DEFAULT_REGION eu-west-1

Windows GPO

Group policy result to html
gpresult /h gpreport.html


Local Group Policy editor
gpedit.msc


GPO Management console:
gpmc.msc


Force GPO update
gpupdate /force

Windows Shutdown

Reboot in 1 second
shutdown -r -t 1


Shutdown in 0 seconds (force option implied)
shutdown -s -t 0

Windows TCP Dump

Note: This needs (portable) tcpdump, the created file can be opened by (portable) wireshark for analysis. See here for more info on tcpdump.

dump traffic with host 10.10.10.10 on interface 1 to file
\tcpdump.exe -i 1 -vv host 10.10.10.10 -w tcpdumpfile.pcap 


dump traffic with host 10.10.10.10 on interface 1 to file with a readable timestamp format
\tcpdump.exe -i 1 -vv host 10.10.10.10 -tttt -nr tcpdumpfile.pcap 

Other

GIT

Check git repository size
git count-objects -vH 


Combine fetch and merge to completely update a repository
git pull 
You could leave a comment if you were logged in.
cheatsheet.txt · Last modified: 2022/08/09 05:50 by sjoerd