Powershell
A collection of some powershell-snippets I found useful, can be found under:
History#
You can get the history of your current powershell session with Get-History
.
To access older history, you can use the file stored under (Get-PSReadLineOption).HistorySavePath
.
In this file a maximum of (Get-PSReadLineOption).MaximumHistoryCount
commands is stored.
With fzf
you can access this list comfortably:
function FuncFuzzySearchHistory(){
$cmd = $(Get-Content $((Get-PSReadLineOption).HistorySavePath) | fzf)
$cmd
Invoke-Expression $cmd
}
Prompt#
To change the behaviour of the powershell prompt before running the command, alter the prompt
-function.
## This sets the window-title with the last three dir of the path
function prompt(){
$three = (Get-Location).Path -split '\\' | Select-Object -Last 3
$path = $three[0] + "\" + $three[1] + "\" + $three[2]
$host.ui.RawUI.WindowTitle = $path
"$(Get-Location)> "
}
Constructing an alias with arguments#
You can use the builtin-args variable for that.
function DotFilesRepo(){
$base = "git.exe --git-dir=$env:USERPROFILE\repos\dotfiles\ --work-tree=$env:USERPROFILE"
$cmd = "$base $args" # The $args-variable is builtin and gets all arguments. Discoverd by accident.
Invoke-Expression -Command $cmd
}
function DotFilesReposStatus(){
dfr status
}
Set-Alias -Name dfr -Value DotFilesRepo
Set-Alias -Name dfrs -Value DotFilesReposStatus
Aliases#
When constructing an alias with the corresponding function, keep in mind that powershell
is not case-sensitive.
That means, Set-Alias -Name wiki -Value Wiki
would set alias that overwrites the function.
My approach to this is to add the appropriate verb to the function name, e.g. Set-Alias -Name wiki -Value EnterWiki
.
Params#
If you want to use flags to activate a function, you can use a [switch]
.
param(
[switch]$SetTaskScheduler = $False,
)
Write-Host $SetTaskScheduler
if ($SetTaskScheduler){
Write-Host "Setting the task"
}
Task Scheduler#
Credentials Object#
If you want to safely pass username and password, you can create a Credentials object
$username = "admin1234"
$password = "mysupersecurepassword"
[securestring]$secStringPassword = ConvertTo-SecureString $password -AsPlainText -Force
[pscredential]$cred = New-Object System.Management.Automation.PSCredential ($username, $secStringPassword)
Powershell Data File#
Instead of using json
, yaml
or another well-known config-file format for your script, you can go the native powershell way with psd1
-file.
A simple one-dimensional config (e.g. config.psd1
) would look like this:
@{
Username = "ftp-user"
Password = "supersecretftppassword"
Exclude = @("PT*0730*.DAT")
}
In your script you would import the config-file and access the variable like properties:
$config = Import-PowershellDataFile -Path ".\config.psd1"
$config.Username
$config.Password
$config.Exclude
Prettify Script#
For reformatting your scripts, you can use the following project: https://github.com/DTW-DanWard/PowerShell-Beautifier
Run it as following: Edit-DTWBeautifyScript .\export.ps1
to update the code.
It is available on scoop
via scoop install main/powershell-beautifier
.
LDAP Query#
When working with powershell, you most certainly are living in a Windows Domain. With this premise you obviously won’t get along without doing some searching in the Active Directoy. With the following powershell-function you can make ldap-queries by using your current Kerberos Authentification. That means:
- Logon with your domain-user.
- Execute the script.
- Get data without inputting user+password.
function GetUser(){
param (
[string]$username
)
# Get the current domain name in DN format
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$domainDN = ($domain.Name -split "\.") -join ",DC="
$domainDN = "DC=$domainDN"
# Edit this to your needs
$userPaths = @(
"OU=Mitarbeiter,OU=IT,OU=Users",
)
foreach ($path in $userPaths) {
$full = "LDAP://$path,$domainDN"
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.SearchRoot = New-Object DirectoryServices.DirectoryEntry($full)
$searcher.Filter = "(&(objectClass=user)(sAMAccountName=*$username*))"
$searcher.PageSize = 1000
$searcher.FindAll() | ? {
$user = $_.GetDirectoryEntry()
# If you want to know all properties of an entry
# you can use this:
# $user.Properties.PropertyNames | ? {
# Write-Host "$_ : $($user.Properties[$_])"
# }
$out = @"
sAMAccountName: $($user.samaccountname.Value)
mail: $($user.mail)
dn: $($user.distinguishedName.Value)
-----------------------------------------
"@
Write-Host $out
}
}
}
CSV Export#
For exporting data into a csv, you can use custom powershell-objects and pipe it to the Export-Csv
function.
$results
foreach ($user in $allUsers) {
$userObj = [PSCustomObject]@{
sAMAccountName = $user.sAMAccountName.value
name = $user.name.value
mail = $user.mail.value
dn = $user.distinguishedName.value
}
$results += $userObj
}
}
# Export the results to a CSV file
$results | Export-Csv -Path "UserData.csv" -NoTypeInformation
Delete UserProfiles via Wmi#
If you don’t have access via WinRM
, you can use WMI
(Windows Management Instrumentation) as an Alternative.
Run this as Domain Administrator.
## Show all profiles
Get-WmiObject -Computername special_hostname -Class Win32_userprofile
## Show profile
Get-WmiObject -Computername special_hostname -Class Win32_userprofile | Where { $_.LocalPath -like "*domainusername*" }
## Delete the profile
Get-WmiObject -Computername special_hostname -Class Win32_userprofile | Where { $_.LocalPath -like "*domainusername*" } | Foreach { $_.Delete() }
You will notice that your user is still present in the LogonUI. Clear out the keys with your username in this Registry-Path:
my-remote-machine\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI
Tips and Tricks#
Get all line of go#
Get-ChildItem -Recurse -Include '*.go' | Get-Content | Measure-Object -Line