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

User Tools

Site Tools


Recently Changed Pages:

View All Pages

View All Tags


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


Cheat Sheet

An overview of all sorts of commands and script usage.


PowerShell Help

Get-Help with -Parameter is a quick way to examine the data type a given parameter expects:
PS> Get-Help Get-ChildItem -Parameter Path
-Path <String[]>
    Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (`.`).
    Required?                    false
    Position?                    0
    Default value                Current directory
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  false

PowerShell History

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

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

PowerShell If

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"

PowerShell Count

Count number of strings / objects
# string
$een = "een"
# Array
$twee = @("een","twee")

# string
$een = "een"
# Array
$twee = @("een","twee")

Measure-Object - Sometimes counting when there is only one item can fail, use measure-object instead.
$een = "een"
($een | Measure-Object).Count
$twee = @("een","twee")
($twee | Measure-Object).Count

PowerShell Dates

# Dates
$timestamp = Get-Date -format "" # 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

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. }

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')
  6. ### Start transcript for full logging capabilities ###
  7. start-transcript -path "$scriptlocation\$scriptname-$date-logtranscript.txt"
  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, '=')

Preference Variables

About Preference Variables

Verbose Preference
# Default
$VerbosePreference = 'SilentlyContinue'
# Override: -Verbose
# Verbose output
$VerbosePreference = 'Continue'
# Override: -Verbose:$false

Debug Preference
# Default
$DebugPreference = 'SilentlyContinue'
# Debug output
$DebugPreference = 'Continue'

Whatif Preference
# Default
$WhatIfPreference = $false
# Override: -WhatIf
# When WhatIf is enabled, the cmdlet reports the expected effect of the command, but doesn't execute the command.
$WhatIfPreference = $true
# Override: -WhatIf:$false

PowerShell Variables

Set system (environment) variable

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 = ""
$script:apiversion = "api-version=6.0"
function SetBuildTag {
  # Load Azure DevOps API settings
  foreach ($tag in $tags){
      $tagurl = "$orgUrl/$env:System_Teamproject/_apis/build/builds/$env:BUILD_BUILDID/tags/$($tag)?$apiversion"

Set system variables with a dash/hyphen
${env:test-app_user} = "svc-test-dev"
$user = ${env:test-app_user}

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 Function Template

See here for guidelines.
function Use-AzureDevOpsApi{ #Use Get-Verb for a list of approved verbs
        Short description
        Long description
        Explain the parameter Pat. Repeat for additional parameters.
        Explain the powershell output, if any
        Pipeline example:
        - task: PowerShell@2
          displayName: "Use Default SystemAccessToken" 
            SYSTEM_ACCESSTOKEN: $(System.AccessToken) 
            pwsh: true
            targetType: 'inline'
            script: |
                # Load Azure DevOps API settings
        Script example:
        Use-AzureDevOpsApi -Pat $Pat
        System access token:
        Author : Sjoerd Hooft
        Version: 2022-08-03 
    param (
        [ValidateLength(52,52)] # See for more paramater validation 
        [ValidateSet("dev", "tst", "acc")]
    begin {
        Write-Host "##[section]Function: $($MyInvocation.MyCommand)"
        Write-Verbose "Input: $($PSBoundParameters | Out-String)"
        # Set Verbose switch based on PSBoundParameters
        $CmdLetOutput = @{Verbose = $($PSBoundParameters.Verbose)}
        # Collect information
    process {
        # Do stuff
    end {
        # Cleanup

PowerShell Function Validates

  • Not null or empty: [ValidateNotNullOrEmpty()]
  • Latest or YYYY-MM: [ValidatePattern("latest|20\d{2}[-]\d{2}")]
  • Email: [ValidatePattern('(.+@getshifting\.com)$')]
  • Specific server name: [ValidatePattern("web(dev|tst|acc)dmz0[12]")]
  • Environment: [ValidateSet("dev", "tst", "acc", "prd")]
  • Number between: [ValidateRange(8,100)]
  • Length range: [ValidateLength(8,12)]
  • Length exactly: [ValidateLength(8,8)]

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 (
Import-Module IISAdministration -RequiredVersion
$mod = Get-Module -Name IISAdministration
$mod.ExportedCmdlets | Format-Table

Import PS Module
Import-Module Pester

Get commands within a module
Get-Command -module Pester

Get module for a command
Get-Command Get-Service

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

# 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>

Windows Management

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 grn* -ComputerName appprd02 | Restart-Service -Verbose

Start all stopped Windows Services
Get-Service -Name grn* -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 ($ -like 'Grn*') -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 IIS Management

Restart all App Pools
& $env:windir\system32\inetsrv\appcmd list apppools /state:Started /xml | & $env:windir\system32\inetsrv\appcmd recycle apppools /in

Note: This does not start stopped app pools

Restart all App Pools Remotely
$servers = 'web01','web02','web03'
Invoke-Command -ComputerName $servers { & $env:windir\system32\inetsrv\appcmd list apppools /state:Started /xml | & $env:windir\system32\inetsrv\appcmd recycle apppools /in }

Note:This does not start stopped app pools

Get the process for a IIS Site (always running under w3wp):
# Site and Appool have the same name:
$site = "customerapi"
processId = (Get-WmiObject -Class win32_process -filter "name='w3wp.exe'" | Where-Object { ($_.CommandLine).Split("`"")[1] -eq $site } ).ProcessId

Note: This one is also listed under Windows Process Management

Windows Certificates

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

Open Current User Certificate store:

Open Local Machine Certificate store:

Get specific details from specific certificates from a list of servers and export to csv
$servers = @("server1","server2","server3")
Invoke-Command -ComputerName $servers {Get-ChildItem Cert:\LocalMachine\My | where-object {(($_.DnsNameList -like  "*rabobank*") -OR ($_.Subject -like "*rabobank*"))} |select-object @{name="hostname";expression={$(hostname)}},DnsNameList,NotAfter,Thumbprint,Subject,Issuer,FriendlyName} | Export-Csv certs.csv -NoTypeInformation

Windows Processes

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

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

Get the process for a IIS Site (always running under w3wp):
# Site and Appool have the same name:
$site = "customerapi"
processId = (Get-WmiObject -Class win32_process -filter "name='w3wp.exe'" | Where-Object { ($_.CommandLine).Split("`"")[1] -eq $site } ).ProcessId

Get the process and child processes:
$id = (Start-Process cmd.exe -PassThru).id
Get-WmiObject -Class Win32_Process -Filter "ParentProcessId = '$id' or ProcessId ='$id'" | Select-Object ParentProcessId,ProcessId,CommandLine

Get all process from a specific path
$dir = "appdir"
Write-Host "Alle processen in Path -like $dir"
Get-CimInstance win32_process -Property * | Where-Object {$_.path -like "*$dir*"}

Kill processes

Kill process and child processes
$id = (Start-Process cmd.exe -PassThru).id
Get-WmiObject -Class Win32_Process -Filter "ParentProcessId = '$id' or ProcessId ='$id'" | Select-Object ParentProcessId,ProcessId,CommandLine | ForEach-Object {Stop-process $_.processId}

Using taskkill
$id = (Start-Process cmd.exe -PassThru).id
# Killing the PID
taskkill /pid $id /t /f
# Or using the image name (executable name without path)
taskkill /im cmd.exe /t /f

Windows System Info

Collect uptime, patches, windows version and more

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

GPO Management console:

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

Active Directory

Active Directory Users

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"

Get the most common reasons on a user for not being able to logon
Get-ADUser User123 -Properties * | Select-Object enabled,passwordexpired,lockedout

Active Directory Servers

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

Active Directory DNS

Get all AD DNS zones with all properties
Get-ChildItem "AD:CN=MicrosoftDNS,DC=DomainDNSZones,DC=getshifting,DC=local" | Select-Object *

Get all records in a DNS zone with all properties
Get-ChildItem "AD:DC=getshifting.local,CN=MicrosoftDNS,DC=DomainDNSZones,DC=getshifting,DC=local" | Select-Object *

Get creation and modify date of AD DNS records
Get-ChildItem "AD:DC=getshifting.local,CN=MicrosoftDNS,DC=DomainDNSZones,DC=getshifting,DC=local" | Where-Object {$ -like "build*"} | Get-ADObject -Properties Created,Modified | Select-Object Name,Created,Modified


Reverse loopup with ping
ping -a

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

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 on interface 1 to file
\tcpdump.exe -i 1 -vv host -w tcpdumpfile.pcap 

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

Remote IPConfig

Renew Ip config remotely without losing access
ipconfig /release && ipconfig /renew

Azure DevOps

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}

Variables in Azure DevOps

Pipeline variable in yaml - without PowerShell
  - name: BuildConfiguration
    value: 'Release'
- task: DotNetCoreCLI@2
  displayName: "Build Solutions"
    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 variables

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 {$ -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
# Stop
docker stop container_id
# default grace time = 10
docker stop --time=5 container_id 
# Start
docker start container_id
# Restart
# Restart apache container by name
docker container restart httpd_web

Get logging from docker container
docker logs --tail 50 --follow --timestamps httpd_web

grep in logging
docker logs <container_name> 2>&1 | grep <string>

Note that docker logs to stderr do you need to redirect this to stdout

Get docker container info
docker inspect container_id

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

Copy a file from or to a container
docker cp tool_db:/var/lib/postgresql/data/pgdata/postgresql.conf ./postgresql.conf

Work Inside a Container

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

As a different user
docker exec -u postgres -it container_id /bin/bash

Docker Compose

Docker compose files are used to start containers. By default, a docker-compose.yml or a docker-compose.yaml file is used.

Start and stop containers from docker-compose file

docker compose up -d
docker compose down

Note the -d switch to start the containers in the background.

See logging
# the logs from each of the services interleaved into a single stream
docker compose logs -f
# the logs just for app
docker compose logs -f app

Docker Build

Docker build, run and show logs of a custom app called privacy
# Build an image called privacyimage
docker build -t privacyimage .
# Run a container called privacycontainer from the image
docker run -d --name privacycontainer privacyimage
# Show the logs from the container
docker logs privacycontainer

# Show all steps in plain output and redo every step (don't use cached steps)
docker build --progress=plain --no-cache  -t consoleappdbtestimage .

Save an image to disk and import somewhere else
# Create a tar file from the consoleappimage
docker save -o ./consoleappimage.tar consoleappimage
# import the image
docker load -i /consoleappimage.tar


A Dockerfile is used to create images:

Default .net app dockerfile:

FROM AS build-env
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "DockerConsoleApp.dll"]



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

find file in current and subdirectories
sudo find . -name

File Management

Compare two files
diff file file2

Compare two files next to each other, only differences
diff -y --suppress-common-lines file1 file2



See release
cat /etc/os-release


  • Turn off syntax :syntax off
  • Delete all below lines, including current: dG
  • Past text from windows clipboard through putty: SHIFT + INS

Certificate Management

Create csr with new private key (preferred)
openssl req -nodes -newkey rsa:2048 -keyout * -out *

Create csr with existing key
openssl req -new -key /data/keys/  -out *

View certificate
openssl x509 -text -noout -in certificate.crt

View csr

openssl req -text -in request.csr

Logfile Management

Truncate a logfile that has grown too big

sudo truncate -s 0 odoo.log


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 to Azure

Login and context
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


These are just a few examples, see Kusto Queries in Azure for more.

Log errors every 10 minutes in a stacked graph
| where RawData contains "error"
| summarize count() by Computer, bin(TimeGenerated, 10m)
| order by TimeGenerated
| render areachart

Week overview of errors per service account in a column graph
| where LogType_CF == '[error]'
| summarize count() by UserName_CF, Computer, bin(TimeGenerated, 1d)
| order by TimeGenerated, UserName_CF
| render columnchart

SQL timeouts in a column graph
| where outerMessage has "timeout" and outerType == "Microsoft.Data.SqlClient.SqlException"
| summarize count() by bin(timestamp, 1d), cloud_RoleName
| order by timestamp
| render columnchart

All exceptions per 30 seconds per application
| where outerMessage contains "timeout"
| where cloud_RoleName != ""
| summarize count() by bin(timestamp, 30s), cloud_RoleName
| order by timestamp

All high severity level exceptions of a specific type
| where severityLevel > 2 and type == 'MassTransit.RequestTimeoutException'
| summarize count() by cloud_RoleName, bin(timestamp, 1d)
| render columnchart


Check git repository size
git count-objects -vH 

Combine fetch and merge to completely update a repository
git pull 

Log & Diff

Show git log
git log

Show the files which have changed between the branch and master
git diff --name-only master..branchtocheck


Create and immediately checkout a branch
git checkout -b "#123456-add-dns-resolving"

Show all branches
git branch -a

Show all active branches
git ls-remote --heads origin

Merge changes from master branch, perform from inside the branch
git merge master

Git Remotes

Show remote
git remote -v

Update the remote “origin” with a new url in case of a rename of the repo or project
git remote set-url origin


Add and commit a new file
git add .
git commit -m "Added new file"

Add and commit in 1 go for changed files
git commit -am "changed a file"

Co-Authoring / Pair coding commit message
Changed a couple of files

Co-Authored-By: Sjoerd <sjoerd @>

VSCode Key Combinations

  • Comment / uncomment: ctrl + /
  • Word wrap: alt + z
  • toggle from editor to terminal: ctrl + `
  • toggle from terminal to editor: ctrl + 1
You could leave a comment if you were logged in.
cheatsheet.txt · Last modified: 2023/04/23 16:15 by sjoerd