Snippets Powershell
Tags: powershell
Basic Where
Get-WindowsOptionalFeature -Online | ?{ $_.State -Like 'Enabled'} | Select FeatureName
Admin check
Run Test-IsAdmin
to call the function and output true or false. I use this for logging. If you want a hard fail for lack of admin use #Requires -RunAsAdministrator
function Test-IsAdmin { try { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal -ArgumentList $identity return $principal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ) } catch { Throw "Failed to determine if the current user has elevated privileges. The error was: '{0}'." -f $_ }}
Start service on remote machine
Get-Service -ComputerName <machine> -Name <service> | Set-Service -Status Running
Grep
<stdout> | findstr -i <term>
Select-String -Path * -Pattern ".*STRING.*" -ErrorAction SilentlyContinue
Connect to Sharepoint online
# the name appearing in the URL of your sharepoint site before sharepoint.com$orgName=""# connect without using get-credential so that the modern prompt is generated allowing 2FAConnect-SPOService -Url https://$orgName-admin.sharepoint.com
Dates
$Date = Get-Date -Format yyyy-MM-dd$Year = Get-Date -Format yyyy$Month = Get-Date -Format MM$Day = Get-Date -Format dd$Hour = Get-Date -Format HH$Minute = Get-Date -Format mm$Second = Get-Date -Format ss$Time = Get-Date -Format HH-mm-ss$TimeStamp = Get-Date -Format s | foreach {$_ -replace ":", "-"}
Remove specific index from array
$array = 1,2,3$newArray = $array | ? { $_ -ne $array[0] }
Remove empty objects from array
$array | Where-Object {$_}
Get Fonts
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
(New-Object System.Drawing.Text.InstalledFontCollection).Families
Check object for property
If (Get-Member -inputobject $OBJECT -name "PROPERTY" -Membertype Properties) { Write-Host 'yes' }
Counting
$i | measure -Line -Character -Word
Date manipulation
Get the date 6 months ago
$date = Get-Date$date.AddMonths(-6)
Parameters
param ( [Parameter(Mandatory=$True)] [Object]$smptTo, [Parameter(Mandatory=$True)] [Object]$messageSubject, [Parameter(Mandatory=$True)] [Object]$messageBody, [Parameter(Mandatory=$False)] [Object]$messageAttachment,)
Replace
This uses regex
$a -replace "boring!$", "exciting!"
Replace in files
ForEach ($file in $(Get-ChildItem -Path "./*" -Recurse -Attributes !Directory)) { $dirty = Get-Content $file $dirty -Replace 'this', 'that' | Set-Content $file}
Splitting
$string = "a powershell $([char]0x007B) string $([char]0x007D) contains stuff"$string.Split("{,}")
With a pipe
$rawData0 -Split "-- S.M.A.R.T"
Timers
#Create a Stopwatch$stopWatch = New-Object -TypeName System.Diagnostics.Stopwatch
#You can use the $stopWatch variable to see it$stopWatch
#Go ahead and check out the methods and properties it has$stopWatch | Get-Member
$stopwatch.Start()$stopwatch.Elapsed$stopwatch.Stop()$stopwatch.Reset()
Try-Catch
try { This is not allowed "This is Allowed"} catch { Write-Host "Error occured" -BackgroundColor DarkRed}
Printing the error that caused the catch
Use Write-Host $_
Get word count from text files recursively
Get-ChildItem -Recurse | Select Name,@{Name='Count'; Expression={(Get-Content $_ | Measure-Object -Word).Words}}
Remove all lines after X from selection/text file
$txt = Get-Content file.txt$to = '## Home'$i = 0Do { $txt[$i++] } Until ($txt[$i] -eq $to)
Simpler
$(Get-Content .\2021-09-27.md -Raw ) -replace '## Home[\s\S]+'
ForEach ($file in (Get-ChildItem -Recurse -Filter '20*.md')) { $(Get-Content $file -Raw) -replace '## Home[\s\S]+' | Set-Content $file}
Remove all work lines form daily notes
$(Get-Content .\2022-01-06.md -Raw) -replace '# Daily[\s\S]+## Home','# Daily'
ForEach ($file in (Get-ChildItem -Recurse -Filter '*.md')) { $(Get-Content $file -Raw) -replace '# Daily[\s\S]+## Home','# Daily' | Set-Content $file}
or
ForEach ($file in (Get-ChildItem -Recurse -Filter '20*.md')) { $(Get-Content $file -Raw) -replace '## Home[\s\S]+' | Set-Content $file}
Get Directory Size
(Get-ChildItem C:\Temp\ -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB(Get-ChildItem C:\Temp\ -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB
Get directory size for every child directory
ForEach ($dir in $(Get-ChildItem -Directory)) { Write-Host $dir.name -ForegroundColor green (Get-Childitem $dir -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB}
Search for file names
Get-Childitem –Path C:\ -Include *Term* -File -Recurse -ErrorAction SilentlyContinue
Get-Childitem –Path C:\ -Include "*Term*" -Exclude "*.png","*.jpg" -File -Recurse -ErrorAction SilentlyContinue
File extensions function
[System.IO.Path]::ChangeExtension("Untitled.md",".new")
File exists
If (Test-Path $vsLayout) { Write-Host "Layout exists" -ForegroundColor Green}
Wait for file to exist
While (!(Test-Path $vsLayout)){ Write-Host "Waiting for layout creation..." -ForegroundColor Yellow Start-Sleep -Seconds 3}
Prepend string to items in array
$test = $jsonConfig.components.ForEach({"--add " + $_})
Get object type
$test.GetType()
Random String
add-type -AssemblyName System.Web[System.Web.Security.Membership]::GeneratePassword(15,2)
Compare 2 directories
Quick way to get just names
$Folder1 = Get-childitem "C:\Folder1"$Folder2 = Get-childitem "C:\Folder2"
$Compare-Object $Folder1 $Folder2 -Property Name
If you need to retain properties
$Folder1 = Get-childitem "C:\Folder1"$Folder2 = Get-childitem "C:\Folder2"
$Difference = $Folder1 | Where {$Folder2.Name -notcontains $_.Name}
Pull differences into a new directory
Copy-Item $Difference.FullName -Destination .\Difference_Directory
If file exists
If (Test-Path C:\filename) { Write-Warning "File exists"}