Skip to content

Instantly share code, notes, and snippets.

@daemonhorn
Last active August 10, 2024 23:57
Show Gist options
  • Save daemonhorn/5b2b535453bb8bacf62929ec8a1552b2 to your computer and use it in GitHub Desktop.
Save daemonhorn/5b2b535453bb8bacf62929ec8a1552b2 to your computer and use it in GitHub Desktop.
Powershell $profile helper examples
# Place this file in our $profile location and restart powershell.
# e.g.: copy Downloads\example.ps1 $profile
# $profile defaults to $HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
# aka: c:\Users\username\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
# If you want to sign it see function `user-sign-psscript` below for signing
# This enables the use of:
# set-executionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser
# Or if you don't care about security on Powershell locally, you can ignore local signing, and just use:
# set-executionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
$debugpreference = "SilentlyContinue"
set-alias -Name npp "C:\Program Files\Notepad++\notepad++.exe"
set-alias -Name notepad++ npp
function setup-wslinterop ($bash_function_name_array) {
<#
.SYNOPSIS
Perform initial configuration of the Windows SubSystem for Linux (WSL) function aliases.
`set-wslinterop vim` - create a new virtual powershell function named `vim` and call the WSL/bash provided `vim` command when invoked.
`set-wslinterop $array` - create a new set of virtual powershell functions based on $array
.DESCRIPTION
- See https://github.com/mikebattista/PowerShell-WSL-Interop for more information and available customization options.
- Invocation of this function will attempt to perform basic sanity checking and initial configuration including:
- Verify modern Powershell is available
- Verify WSL is available
- Download, Install, Import `WSLInterop` module from PSGallery
- Check if signing is enforced, and attempt to self-sign PSGallery module and add trust if needed
- Configure hardcoded values for user preferences for environment or default arguments (customize this file or other variables as desired)
- Specifically setup virtual functions for every element in the $array passed into this function that map into WSL/Linux/Bash functions
#>
# https://github.com/mikebattista/PowerShell-WSL-Interop
if (-not ($psversiontable.PSEdition -like "Core")) {
Write-Warning "Requires a modern version of Powershell Core."
Write-Warning "See https://aka.ms/powershell-release?tag=stable or https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows for more information"
}
if (-not (Invoke-Expression "wsl.exe --status")) {
# Windows Subsystem for Linux error check using wsl --status
return $false
} else
{
if ( -not (get-module WslInterop -ListAvailable) ) {
Write-Warning "Performing initial install of Powershell Gallery module: WslInterop..."
Install-Module WslInterop
$current_policy = get-executionpolicy
if ( $current_policy -ilike "*allsigned*" ) {
$mod_path = (get-installedmodule wslinterop).InstalledLocation + "\wslinterop.psm1"
Write-Warning "Signing WslInterop module to allow execution. If prompted to trust a new certificate, click yes."
user-sign-psscript "$mod_path"
}
Import-Module WslInterop
#bash -ic "sudo apt install bash-completion dnsutils tmux -y"
}
# Dynamically create powershell functions that map to wsl commands (bash commands or native linux utils, etc.)
Import-WslCommand $bash_function_name_array
# Default prefixed arguments for invoked functions
$global:WslDefaultParameterValues = new-object([System.Collections.Hashtable])
$global:WslDefaultParameterValues["ls"] = "-alF --group-directories-first --color"
$global:WslEnvironmentVariables = new-object([System.Collections.Hashtable])
#WSL environment variables for the invoked functions
$global:WslEnvironmentVariables["PAGER"] = "/usr/bin/less -X"
Write-Host -Foregroundcolor Green -NoNewLine 'The following wsl bash functions were imported : '
Write-Host -Foregroundcolor yellow $bash_function_name_array
}
}
function user-sign-psscript ($File){
<#
.SYNOPSIS
Perform lightweight automatic authenticode sign and trust operations on powershell scripts to enable more secure defaults.
`user-sign-psscript example.ps1` <Sign and trust the file named example.ps1>
`user-sign-psscript` <Sign and trust the $profile file>
.DESCRIPTION
- If there is a code signing certificate and key in the Windows certificate store under Personal\Certificates (aka CurrentUser\My), use it for the next step.
- If there is no applicable certificate, create a new self-signed certificate using the current username/domain in the CN field.
- Copy Certificate to the Trusted Root store for the Current User (does not require admin)
- Copy Certificate to the Trusted Publisher store for the Current User (does not require admin)
- Perform Set-AuthenticodeSignature on the passed in file name with the applicable certificate.
#>
[DateTime] $ValidThrough = (Get-Date)
# Check to see if there is one in the cert store and use it
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Where-Object { $_.NotAfter -gt $ValidThrough } | Select-Object -First 1
if ( -not $cert ) {
#Create self-signed cert
$params = @{
Subject = "CN=$env:USERNAME@$env:USERDOMAIN PowerShell CodeSigning"
Type = 'CodeSigning'
CertStoreLocation = 'Cert:\CurrentUser\My'
HashAlgorithm = 'sha256'
}
$cert = New-SelfSignedCertificate @params
# You can change these to LocalMachine instead of CurrentUser, but requires admin. For portability, leaving as user.
$RootcertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "CurrentUser")
$RootcertStore.Open("ReadWrite")
# Will cause a dialog to appear for confirmation.
$RootcertStore.Add($cert)
$RootcertStore.Close()
$PubcertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("TrustedPublisher", "CurrentUser")
$PubcertStore.Open("ReadWrite")
$PubcertStore.Add($cert)
$PubcertStore.Close()
}
if ( -not $File) { $File = $profile }
if ( Test-Connection timestamp.digicert.com -tcpport 80 -ErrorAction SilentlyContinue ) {
Set-AuthenticodeSignature $File $cert -TimestampServer 'http://timestamp.digicert.com' | select-object Status, StatusMessage, Path
}
else {
Write-Warning "No connectivity to timestamp server at http://timestamp.digicert.com, falling back to no timestamp counter-signature"
Set-AuthenticodeSignature $File $cert | select-object Status, StatusMessage, Path
}
}
$bash_function_name_array = "vi", "ssh-copy-id", "grep", "sed", "cut", "ls", "uname", "tmux", "dig", "host", "man", "openssl", "tail", "find", "head", "less", "which", "env"
setup-wslinterop $bash_function_name_array
# SIG # Begin signature block
# MIIcBAYJKoZIhvcNAQcCoIIb9TCCG/ECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBWkCGyiiuGJ+Dq
# KNRQwaAb1Bhb4j6xAfGCvNFAyQQNtaCCFj8wggMyMIICGqADAgECAhAk1FGqI0US
# rE4Yp3B0xBu7MA0GCSqGSIb3DQEBCwUAMDExLzAtBgNVBAMMJmRob3JuQERFTEwt
# NzU1MCBQb3dlclNoZWxsIENvZGVTaWduaW5nMB4XDTI0MDgwNDIwNTU0OVoXDTI1
# MDgwNDIxMTU0OVowMTEvMC0GA1UEAwwmZGhvcm5AREVMTC03NTUwIFBvd2VyU2hl
# bGwgQ29kZVNpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDv
# HzRnXVKCTEBDB9IPK0hvjLNuZEqwGlpHfrwmCwJKFvR3O9J6TVxbfFEVrIRpiamH
# gu2vu0oAcM03Uo6dJNW7lgxQfx0tq6Ga6HI8t2w4RRUQZpDUxS2I12Rz9OhwpVnc
# aDfFGDHjr47D1N3fVBmRpiCCuC4h/nz9vHdjOrSfu1eFfSWMQl6doBPf8pUT19Ra
# vA/iYKCFP1iNseTe9gGWR5PYWKaUqX4YpookUPneqrH4Pa+TKVczaxJmEQxxpEEu
# gF8SK9DFIoLYcALVID0lrJHqiq9lFkyOI75maDoBrzigISS5Fsvt+sYSJHQt1FyN
# +J2FlW91QJ0NLy3I/ogpAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUE
# DDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUu1CgaZnncV3e+QlaJmxET2GuRmkwDQYJ
# KoZIhvcNAQELBQADggEBAFYHVJFozqVMwT/dz+vPL9aGSMxFTTBDdIp6irK1vXnG
# aaqXDQR/a/+AAr63Qc9WwJfyU8xkp5exqiUvoqT1fF07lr2U8xvqNp60DmpKXhnR
# PRtJ2rvKnaK6bN+FCUQfNm9eYELG3GgZO3zhGSTx9wPehhFwOE0YY7lmMyJLxSxe
# 18Upn+3EbdChKY4aN69nf225usz6WTMIMOu4d21jHZRnOuOgs1z6haqK/FqwKtMk
# 1vrz7gqJJHCHn5b+A60jn7D2hxSWDu5gv3Fp4j+v0mvY/ZKEgmm6VFgxsjPB4fmX
# co8qf6SfULC9adrq3Iw0zvv+I+zEoMBkMrV3u72M8W4wggWNMIIEdaADAgECAhAO
# mxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUw
# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
# JDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEw
# MDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE
# aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMT
# GERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIP
# ADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprN
# rnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVy
# r2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4
# IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13j
# rclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4Q
# kXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQn
# vKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu
# 5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/
# 8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQp
# JYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFf
# xCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGj
# ggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/
# 57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8B
# Af8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
# cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
# ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6
# oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElE
# Um9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEB
# AHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0a
# FPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNE
# m0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZq
# aVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCs
# WKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9Fc
# rBjDTZ9ztwGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5b
# MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD
# ZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5
# NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkG
# A1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3Rh
# bXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPB
# PXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/
# nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLc
# Z47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mf
# XazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3N
# Ng1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yem
# j052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g
# 3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD
# 4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDS
# LFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwM
# O1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU
# 7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/
# BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0j
# BBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8E
# PDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz
# dGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEw
# DQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPO
# vxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQ
# TGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWae
# LJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPBy
# oyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfB
# wWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8l
# Y5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/
# O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbb
# bxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3
# OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBl
# dkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt
# 1nz8MIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsF
# ADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNV
# BAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1w
# aW5nIENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2Vy
# dCBUaW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AKNTRYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq
# 3RApih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHy
# z8sHpjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkP
# G2ZS48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40Qr
# StWVzu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52
# fTGZZUdVnUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2q
# TGaDiGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6M
# qqtQFcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZW
# pST618RrIbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM
# /vC2x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK
# 8SgTIUlRfgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAO
# BgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEF
# BQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgw
# FoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqll
# MaPe1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
# bS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5j
# cmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
# aWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdD
# QS5jcnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzk
# zepdIpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJh
# N2hJd6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703
# DNiYdk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE
# 0PjlSXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVY
# JmoDRd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3a
# EUuMMsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhf
# ysLcPTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIAR
# yxQMfq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6r
# r3M66ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBci
# I0707NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZ
# rZCARK+AEEGKMYIFGzCCBRcCAQEwRTAxMS8wLQYDVQQDDCZkaG9ybkBERUxMLTc1
# NTAgUG93ZXJTaGVsbCBDb2RlU2lnbmluZwIQJNRRqiNFEqxOGKdwdMQbuzANBglg
# hkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV
# MC8GCSqGSIb3DQEJBDEiBCCjmSpVwtvu5S9zO1AfWVP3r2MQVZTTA/CiIcDhHsRv
# dzANBgkqhkiG9w0BAQEFAASCAQDushbVFFlitqwallazQyNP5Gg1zNZKuh/37pgJ
# rK6mE+zWqa8Iy64N5M0QBYJYHg7EBf5xmfUdOklNFJG8dKtgQ+APXU/u4FNA8LrH
# KrWHZjIydRc5ojoeqSu5G0nrzg0pItOVJPAnOljSVOie+TCMi4kRGabV022TmT6Q
# 8HfBssjtr+QGp9BpNcV/UBvxMQ1UDy/QLZje2hWc4AY+oFRrky0JgYsGp4R2urY7
# xC2WQHzphqp3of4WC+cePlNLQKXQv38PJyozNbdZyO8RWdE+GoC6OxzqDB5HW25E
# Or7bAtJLJboUrhLzwydz6WWUoAfrpEVhxoGGWfNL0O/zmbtSoYIDIDCCAxwGCSqG
# SIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp
# Z2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQw
# OTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglg
# hkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN
# AQkFMQ8XDTI0MDgxMDE4MTczMVowLwYJKoZIhvcNAQkEMSIEIG4J1BqM56SQJVqW
# qaXusKOoBbdvWdRUo7k+BImfflpiMA0GCSqGSIb3DQEBAQUABIICAEOxsXVlLek/
# mEEeaLPKVDimQIlkU2PkD/+X3fwushgTtAYhr0wpIUJ9mbWZWGF/ZbC42fajDCqA
# /1h0jVY4TqhZISwK/2S9V7wkUNGqEaQObW/6UXdVN96nzRIF3vMbGKkZ/rGF6/bT
# 84hND9bO0x1aTZynenmPvEpbg63Ht30ySvfmYT/vKz6xy1mOphCOzDYia+RZy9Pv
# ykcnMXdHMMj3LXIeBn80eQQyx3EVy20eBy+tFpWfHs0jF1pzWj2zOmdZw7Rmm3be
# hveJ8lx2Iw3HFKMDOZF6ElJEvV0IPVnKfn+DlJstVhDxdrkqab7MFl565ov6ve7G
# bexFtcYe02Fcod2YK2WqryfBQKysvtyRcCtMJTFW5yZYDdr6441hQIwFDjVgvJD3
# AeM2IUFY28hsfZkfQu57WqXUjnUgScsbxYGP3PV/1uf5o6woiz/huQkVzwyQCHzD
# 7vAmPuiZM47T4dgztC5x1I+xheuCknQfLXwMolR2yZTg1fV6UQq1coTom2+WIRY/
# qL5mJp/U9slU8MD+eQAZGS70vCsP1uqV/qSmGzk9d+td6zg9iExerx9ipvL72BHk
# P469bgcOqUNdpF6P2i35L9JqcQARVGFZNXvLfasUzGGVsLwhheCpbESrvShqGrLI
# mHiK1I7bt24YOmApU6BhlpLAV8ylWWEh
# SIG # End signature block

Powershell Helpers

This includes examples for how to configure powershell startup scripts for a useful configuration.

  • Requires:
    • Windows Subsystem for Linux (installed and working) e.g.: wsl --install Debian
    • Linux (under wsl) should be upto date, and have desired packages installed e.g.:
     bash
     apt update; apt upgrade
     apt install dnsutils tmux man ssh bash-completion
     umask 077; mkdir ~/.ssh; #for ssh-copy-id to have a place to work from
# Place this file in our $profile location and restart powershell.
#  e.g.:   copy Downloads\example.ps1 $profile
#     $profile defaults to $HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
#     aka: c:\Users\username\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
# If you want to sign it see function `user-sign-psscript` below for signing
# This enables the use of: 
#    set-executionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser
# Or if you don't care about security on Powershell locally, you can ignore local signing, and just use:
#    set-executionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

$debugpreference = "SilentlyContinue"

set-alias -Name npp "C:\Program Files\Notepad++\notepad++.exe"
set-alias -Name notepad++ npp


function setup-wslinterop ($bash_function_name_array) {
	<#
	.SYNOPSIS
	Perform initial configuration of the Windows SubSystem for Linux (WSL) function aliases.
	
		`set-wslinterop vim`  		- create a new virtual powershell function named `vim` and call the WSL/bash provided `vim` command when invoked.
		`set-wslinterop $array`     - create a new set of virtual powershell functions based on $array
		
	.DESCRIPTION
	- See https://github.com/mikebattista/PowerShell-WSL-Interop for more information and available customization options.
	- Invocation of this function will attempt to perform basic sanity checking and initial configuration including:
		- Verify modern Powershell is available
		- Verify WSL is available
		- Download, Install, Import `WSLInterop` module from PSGallery
		- Check if signing is enforced, and attempt to self-sign PSGallery module and add trust if needed
	- Configure hardcoded values for user preferences for environment or default arguments (customize this file or other variables as desired)
	- Specifically setup virtual functions for every element in the $array passed into this function that map into WSL/Linux/Bash functions
		
	#>
	# https://github.com/mikebattista/PowerShell-WSL-Interop
	if (-not ($psversiontable.PSEdition -like "Core")) {
		Write-Warning "Requires a modern version of Powershell Core."
		Write-Warning "See https://aka.ms/powershell-release?tag=stable or https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows for more information"
	}
	if (-not (Invoke-Expression "wsl.exe --status")) { 
		# Windows Subsystem for Linux error check using wsl --status
		return $false 
	} else
	{ 
		if ( -not (get-module WslInterop -ListAvailable) ) {
			Write-Warning "Performing initial install of Powershell Gallery module: WslInterop..."
			Install-Module WslInterop
			$current_policy = get-executionpolicy
			if ( $current_policy -ilike "*allsigned*" ) {
				$mod_path = (get-installedmodule wslinterop).InstalledLocation + "\wslinterop.psm1"
				Write-Warning "Signing WslInterop module to allow execution.  If prompted to trust a new certificate, click yes."
				user-sign-psscript "$mod_path"
			}
			Import-Module WslInterop
			#bash -ic "sudo apt install bash-completion dnsutils tmux -y"
		}
		# Dynamically create powershell functions that map to wsl commands (bash commands or native linux utils, etc.)
		Import-WslCommand $bash_function_name_array
		# Default prefixed arguments for invoked functions
		$global:WslDefaultParameterValues = new-object([System.Collections.Hashtable])
		$global:WslDefaultParameterValues["ls"] = "-alF --group-directories-first --color"
		$global:WslEnvironmentVariables = new-object([System.Collections.Hashtable])
		#WSL environment variables for the invoked functions
		$global:WslEnvironmentVariables["PAGER"] = "/usr/bin/less -X"
		Write-Host -Foregroundcolor Green -NoNewLine 'The following wsl bash functions were imported : '
		Write-Host -Foregroundcolor yellow	$bash_function_name_array	
	}
}


function user-sign-psscript ($File){
	<#
	.SYNOPSIS
	Perform lightweight automatic authenticode sign and trust operations on powershell scripts to enable more secure defaults.
	
		`user-sign-psscript example.ps1`  <Sign and trust the file named example.ps1>
		`user-sign-psscript`			  <Sign and trust the $profile file>
		
	.DESCRIPTION
	- If there is a code signing certificate and key in the Windows certificate store under Personal\Certificates (aka CurrentUser\My), use it for the next step.
	- If there is no applicable certificate, create a new self-signed certificate using the current username/domain in the CN field.
	- Copy Certificate to the Trusted Root store for the Current User (does not require admin)
	- Copy Certificate to the Trusted Publisher store for the Current User (does not require admin)
	- Perform Set-AuthenticodeSignature on the passed in file name with the applicable certificate.	
	#>
	
[DateTime] $ValidThrough = (Get-Date)
# Check to see if there is one in the cert store and use it
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Where-Object { $_.NotAfter -gt $ValidThrough } | Select-Object -First 1
if ( -not $cert ) {
    #Create self-signed cert
    $params = @{
        Subject = "CN=$env:USERNAME@$env:USERDOMAIN PowerShell CodeSigning"
        Type = 'CodeSigning'
        CertStoreLocation = 'Cert:\CurrentUser\My'
        HashAlgorithm = 'sha256'
        }
    $cert = New-SelfSignedCertificate @params
    # You can change these to LocalMachine instead of CurrentUser, but requires admin.  For portability, leaving as user.
    $RootcertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "CurrentUser")
    $RootcertStore.Open("ReadWrite")
    # Will cause a dialog to appear for confirmation.
    $RootcertStore.Add($cert)
    $RootcertStore.Close()
    $PubcertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("TrustedPublisher", "CurrentUser")
    $PubcertStore.Open("ReadWrite")
    $PubcertStore.Add($cert)
    $PubcertStore.Close()
    }
if ( -not $File) { $File = $profile }
if ( Test-Connection timestamp.digicert.com -tcpport 80 -ErrorAction SilentlyContinue ) {
	Set-AuthenticodeSignature $File $cert -TimestampServer 'http://timestamp.digicert.com' | select-object Status, StatusMessage, Path
	}
else {
	Write-Warning "No connectivity to timestamp server at http://timestamp.digicert.com, falling back to no timestamp counter-signature"
	Set-AuthenticodeSignature $File $cert | select-object Status, StatusMessage, Path
	}
}

$bash_function_name_array = "vi", "ssh-copy-id", "grep", "sed", "cut", "ls", "uname", "tmux", "dig", "host", "man", "openssl", "tail", "find", "head", "less", "which", "env"
setup-wslinterop $bash_function_name_array
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment