PowerShell

From Giki

Add-Type if not already exists

source: https://www.thetopsites.net/article/54194919.shtml

if (-not("TrustAllCertsPolicy" -as [type])) {
    Add-Type "using System.Net;using System.Security.Cryptography.X509Certificates;public class TrustAllCertsPolicy : ICertificatePolicy {public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) {return true;}}"
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

Convert from unix epoch to datetime

source: https://newbedev.com/convert-unix-time-with-powershell

Function Convert-FromUnixTimeStamp($UnixTimeStamp) {
   [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($UnixTimeStamp))
}

Date formats

RFC1123

source: https://stackoverflow.com/a/56174627

Get-Date -Format r

Output: Thu, 16 May 2019 09:21:01 GMT

"XML style"

source: https://stackoverflow.com/questions/2249619/how-to-format-a-datetime-in-powershell/56174627#comment99463335_56174627

Get-Date -Format o

Output: 2019-05-16T09:21:01.6784531+02:00

File date time

Get-Date -Format FileDateTime

Output: 20190516T0921016784

Download a file

(New-Object System.Net.WebClient).DownloadFile($sourceUrl,$targetFilePath)

Dynamically add and remove entries from Array

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

#add entry to array
$valueArray.Add($value)

#remove entry at first position from array
$valueArray.RemoveAt(0)

Invoke-WebRequest and Invoke-RestMethod returns 401 (PowerShell < 7)

source: https://hochwald.net/invoke-webrequest-and-invoke-restmethod-get-401-unauthorized-without-any-reason/

the header always has Expect: 100-continue which some APIs can't handle

if ([Net.ServicePointManager]::Expect100Continue -ne $false) {
  [Net.ServicePointManager]::Expect100Continue = $false
}

Ignore certificate errors

source: https://stackoverflow.com/a/46067121

if (-not("dummy" -as [type])) {
    add-type -TypeDefinition @"
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public static class Dummy {
    public static bool ReturnTrue(object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors) { return true; }

    public static RemoteCertificateValidationCallback GetDelegate() {
        return new RemoteCertificateValidationCallback(Dummy.ReturnTrue);
    }
}
"@
}
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = [dummy]::GetDelegate()

Print office document to PDF

source: https://stackoverflow.com/questions/65760455/how-to-automate-print-to-pdf-with-windows-powershell

Function Printto-PDF ($filepath) {
  $VerbosePreference = "Continue"
  add-type -AssemblyName microsoft.VisualBasic
  add-type -AssemblyName System.Windows.Forms
  $focus = 2000
  $FilePath = Get-Item $Filepath
  $newfile = $Filepath.basename + '.pdf'
  Start-Process $Filepath.fullname -verb Print | out-printer -name "Microsoft print to PDF"  
  start-sleep -Milliseconds $focus
  [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
  start-sleep -Milliseconds 250
  [System.Windows.Forms.SendKeys]::SendWait($newfile)
  start-sleep -Milliseconds 250
  [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
  start-sleep -Milliseconds 1500
}

Prioritise multiple network cards - set metrcis

valid values for parameter InterfaceMetric: 1 to 9999

Get-NetIPInterface

Set-NetIPInterface -InterfaceIndex 10 -InterfaceMetric 9999

PSObject

Create PSCustomObject

[pscustomobject]@{
  'name'='value'
  'another'='value'
}

[pscustomobject][ordered]@{
  'name'='value'
  'another'='value'
}

Add NoteProperty

Add-Member -InputObject $PSObject -Type NoteProperty -Name $name -Value $value

TLS 1.2

every now and then I have to install a package from the powershell gallery. this is the cure:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

UTF8 No Bom

$fileArray = Get-ChildItem -Path $folder.FullName -Recurse -Filter "*.txt"

foreach($file in $fileArray) {
	$filePath = $file.FullName
	$content = Get-Content -Path $filePath

	$utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($false)
	[System.IO.File]::WriteAllLines($filePath, $content, $utf8NoBomEncoding)
        # using Out-File did not work!
	#Out-File -FilePath $filePath -Encoding utf8 -InputObject $content
}

UTF8 String Conversion (Umlauts, Emoji, etc.)

function ConvertTo-UTF8String($String) {
    $bytes = [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($String)
    $utf8string = [System.Text.Encoding]::UTF8.GetString($bytes)
    return $utf8string
}

show available encodings

[System.Text.Encoding]::GetEncodings()

finding the right encoding

foreach($codepage in ([System.Text.Encoding]::GetEncodings()).codepage) {
    $bytes = [System.Text.Encoding]::GetEncoding($codepage).GetBytes($String)
    $codepage, [System.Text.Encoding]::UTF8.GetString($bytes) -join ' :: '
}

Uninstall Chrome

source: https://stackoverflow.com/questions/40865484/how-can-i-uninstall-google-chrome-using-power-shell#50413082

(Get-ItemProperty -path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome').version | ForEach-Object {& ${env:ProgramFiles(x86)}\Google\Chrome\Application\$_\Installer\setup.exe --uninstall --multi-install --chrome --system-level --force-uninstall}

Windows Defender

Exclude paths

Add-MpPreference -ExclusionPath "C:\tmp\","C:\scripts"
#to (re-)set the exclusion path:
#Set-MpPreference -ExclusionPath 'C:\tmp\'

Disable real time monitoring

Set-MpPreference -DisableRealtimeMonitoring $true

Uninstall Windows Defender

Uninstall-WindowsFeature -Name Windows-Defender

XML

Read XML

$filePath = 'c:\path\to\file.xml'
[XML]$xmlObject = Get-Content -Path $filePath

Edit XML

$xmlObject.Settings.SettingString = $settingString.ToString()

Save XML

$xmlObject.Save($filePath)

Output XML

source: https://stackoverflow.com/questions/6142053/powershell-output-xml-to-screen#22639013

function Out-XML ([xml]$XmlObject) {
    $StringWriter = New-Object System.IO.StringWriter
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter
    $XmlWriter.Formatting = "indented"
    $XmlObject.WriteTo($XmlWriter)
    $XmlWriter.Flush()
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString()
}

Capture standard output / error from executable

source: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process/66700583#66700583

function Invoke-Process {
    [CmdletBinding(SupportsShouldProcess)]
    param
        (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$FilePath,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$ArgumentList,

        [ValidateSet("Full","StdOut","StdErr","ExitCode","None")]
        [string]$DisplayLevel
        )

    $ErrorActionPreference = 'Stop'

    try {
        $pinfo = New-Object System.Diagnostics.ProcessStartInfo
        $pinfo.FileName = $FilePath
        $pinfo.RedirectStandardError = $true
        $pinfo.RedirectStandardOutput = $true
        $pinfo.UseShellExecute = $false
        $pinfo.WindowStyle = 'Hidden'
        $pinfo.CreateNoWindow = $true
        $pinfo.Arguments = $ArgumentList
        $p = New-Object System.Diagnostics.Process
        $p.StartInfo = $pinfo
        $p.Start() | Out-Null
        $result = [pscustomobject]@{
            Title = ($MyInvocation.MyCommand).Name
            Command = $FilePath
            Arguments = $ArgumentList
            StdOut = $p.StandardOutput.ReadToEnd()
            StdErr = $p.StandardError.ReadToEnd()
            ExitCode = $p.ExitCode
        }
        $p.WaitForExit()

        if (-not([string]::IsNullOrEmpty($DisplayLevel))) {
            switch($DisplayLevel) {
                "Full" { return $result; break }
                "StdOut" { return $result.StdOut; break }
                "StdErr" { return $result.StdErr; break }
                "ExitCode" { return $result.ExitCode; break }
            }
        }
    } catch {
        exit
    }
}

Read PDF content

source: http://allthesystems.com/2020/10/read-text-from-a-pdf-with-powershell/

function convert-PDFtoText {
	param(
		[Parameter(Mandatory=$true)][string]$file
	)	
	Add-Type -Path "C:\ps\itextsharp.dll"
	$pdf = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $file
	for ($page = 1; $page -le $pdf.NumberOfPages; $page++){
		$text=[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdf,$page)
		Write-Output $text
	}	
	$pdf.Close()
}
$file = "C:\Path\To\PDF.pdf"
$text = convert-PDFtoText $file