{"id":28240363,"url":"https://github.com/superswan/powershell-sysadmin","last_synced_at":"2025-06-11T14:32:51.249Z","repository":{"id":77220537,"uuid":"226395737","full_name":"superswan/Powershell-SysAdmin","owner":"superswan","description":"SysAdmin stuff using the all powerful powersehll","archived":false,"fork":false,"pushed_at":"2025-04-20T07:00:53.000Z","size":299,"stargazers_count":26,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-19T03:13:04.587Z","etag":null,"topics":["powershell","scripts","sysadmin","windows"],"latest_commit_sha":null,"homepage":"","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/superswan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-06T19:29:10.000Z","updated_at":"2025-04-20T07:00:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"d3fab16b-19a6-49fc-9be7-6b13e3c38636","html_url":"https://github.com/superswan/Powershell-SysAdmin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superswan%2FPowershell-SysAdmin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superswan%2FPowershell-SysAdmin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superswan%2FPowershell-SysAdmin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superswan%2FPowershell-SysAdmin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/superswan","download_url":"https://codeload.github.com/superswan/Powershell-SysAdmin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superswan%2FPowershell-SysAdmin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259280658,"owners_count":22833432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["powershell","scripts","sysadmin","windows"],"created_at":"2025-05-19T03:13:04.135Z","updated_at":"2025-06-11T14:32:51.234Z","avatar_url":"https://github.com/superswan.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"![header](https://capsule-render.vercel.app/api?type=waving\u0026color=012456\u0026fontColor=ffffff\u0026height=150\u0026section=header\u0026fontAlignY=38\u0026text=Powershell%20Reference\u0026fontSize=60)\n\n# Powershell Reference\n\nA collection of commands, code snippets, and scripts tailored for managing and automating tasks in a Windows environment. Designed for experienced administrators, this resource delves beyond basic PowerShell usage, offering practical solutions for a variety of scenarios.\n\nYou can access a number of these commands via a simple menu by running the following command. The commands are defined in `commands.json` located in this repo\n\n```powershell\nInvoke-WebRequest -Uri \"https://raw.githubusercontent.com/superswan/Powershell-SysAdmin/refs/heads/master/psreference.ps1\" -UseBasicParsing | Invoke-Expression\n```\n\n**Short Version:**\n\n```powershell\niwr 3to.moe/psr | iex \n```\n\n* [Practice](#practice)\n* [One-Liners](#one-liners)\n* [Snippets](#snippets)\n* [Active Directory](#active-directory)\n* [Microsoft 365](#microsoft-365)\n* [Scripts](#scripts)\n* [Windows Defender](#windows-defender)\n* [Fun](#fun)\n\n#### Install Winget\n\n```powershell\nInvoke-WebRequest -Uri \"https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle\" -OutFile \"C:\\WinGet.msixbundle\"\nAdd-AppxPackage \"C:\\WinGet.msixbundle\"\nAdd-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.Winget.Source_8wekyb3d8bbwe\n```\n\n---\n\n## Practice\n\nNot sure if the slack channel is active usually it's the name of the exercise with a 1 at the end like `century1`\n\n[Under The Wire](https://underthewire.tech)\n\n## Combinging Powershell output with Linux programs (WSL2)\n\nIf a wsl2 distro is installed commands from the default distro can be called with `wsl` this can be combined with `Convert-To-JSON` to use common linux data-wrangling tools like `awk`, `sed`, and `grep`\n\n```powershell\nget-hotfix | ConvertTo-Json | wsl jq '.[] | .HotFixID' | wsl sort\n```\n\n## One-Liners\n\n#### Execute last command (Equivalent to Bash `!!`)\n```\nInvoke-History -Id (Get-History -Count 1).Id\n```\n\n#### Close All Open Windows\n\n```\nGet-Process | Where-Object { $_.MainWindowTitle } | Stop-Process\n```\n\n#### Kill processes by company/vendor\n\nLike when you can't uninstall Creative Cloud\n\n```powershell\nGet-Process | Where-Object {$_.Company -like \"*Adobe*\"} | Stop-Process -Force\n```\n\n#### Get Shutdown Events\n\n```\nGet-WinEvent -LogName System | Where-Object { $_.ID -eq 6006 -or $_.ID -eq 6008 -or $_.ID -eq 1074 } | Format-List -Property TimeCreated, ID, Message\n```\n\n#### Get Active Directory User Info\n\n```\nGet-ADUser -Filter \"Name -like '*partofname*'\"\n```\n\n#### Get Domain Name\n\n``$domain = []::GetCurrentDomain().Name``\n\n#### Find Domain Controller using DNS\n\n``Resolve-DnsName -Name \"_ldap._tcp.dc._msdcs.$domainName\" -QueryType SRV``\n\n#### \"Pong Command\" - Listen for Pings. Uses WinDump.exe\n\n``.\\WinDump.exe -i 3 icmp and icmp[icmp-echoreply]=icmp-echo``\n\n#### Enable/Disable Firewall (All Profiles)\n\n``Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False``\n\n#### Enable File and Printer Sharing\n\n``Set-NetFirewallRule -DisplayGroup \"File And Printer Sharing\" -Enabled True``\n\n#### Enable Linked Connections (Administrative and regular user accounts can see the same network shares)\n\n``reg add HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System /v EnableLinkedConnections /t REG_DWORD /d 1 /f``\n\n#### Enable ICMP\n\n``netsh advfirewall firewall add rule name=\"Allow incoming ping requests IPv4\" dir=in action=allow protocol=icmpv4 ``\n\n#### Prefer IPv4 over IPv6\n\nThis adjusts the IPv6 prefix policies so that IPv4 addresses are preferred (Ping, DNS Resolution, etc.). Run both commands.\n\n``netsh int ipv6 set prefixpolicy ::ffff:0:0/96 46 4``\n\n``netsh int ipv6 set prefixpolicy ::/0 45 6``\n\n#### Reset networking stack\n\n``netsh int ip reset``\n\n``netsh winsock reset``\n\n#### Forcefully open Internet Explorer\n\n``mshta.exe \"javascript:open();close();\"``\n\n### Remote Manage\n\n#### Enable RDP\n\n``reg add \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\" /v fDenyTSConnections /t REG_DWORD /d 0 /f``\n\n#### Set NLA\n\n``Set-ItemProperty ‘HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp\\‘ -Name “UserAuthentication” -Value 1``\n\n#### Firewall Rule\n\n``Enable-NetFirewallRule -DisplayGroup “Remote Desktop”``\n\n#### Bloatware Remover (Outdated)\n\n``iex ((New-Object System.Net.WebClient).DownloadString('https://git.io/debloat'))``\n\n#### Remote Event Viewer\n\n``  Set-NetFirewallRule -DisplayGroup 'Remote Event Log Management' -Enabled True -PassThru``\n\n#### Update computers remotely\n\n``Invoke-WuJob -ComputerName $Computers -Script { ipmo PSWindowsUpdate; Install-WindowsUpdate -AcceptAll -IgnoreReboot | Out-File \"C:\\Windows\\PSWindowsUpdate.log\"} -RunNow -Confirm:$false -Verbose -ErrorAction Ignore``\n\n#### Ctrl + WIN + Shift + B (GPU Reset)\n\n``Add-Type -TypeDefinition 'using System;using System.Runtime.InteropServices;public class Keyboard {[DllImport(\"user32.dll\")]public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);}' ; [Keyboard]::keybd_event(0x11, 0, 0, 0); [Keyboard]::keybd_event(0x10, 0, 0, 0); [Keyboard]::keybd_event(0x5B, 0, 0, 0); [Keyboard]::keybd_event(0x42, 0, 0, 0); [Keyboard]::keybd_event(0x42, 0, 2, 0); [Keyboard]::keybd_event(0x5B, 0, 2, 0); [Keyboard]::keybd_event(0x10, 0, 2, 0); [Keyboard]::keybd_event(0x11, 0, 2, 0);``\n\n#### Get creds from IE and Edge\n\n``powershell -nop -exec bypass -c “IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/2K75g15’)\"``\n\n```\n[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] $vault = New-Object Windows.Security.Credentials.PasswordVault $vault.RetrieveAll() | ForEach {$vault.Remove($_)}\n```\n\n#### Count Mailboxes based on office or chosen property\n\n``Get-Mailbox | Group-Object -Property:Office | Select-Object name,count``\n\n#### Get all PC Names according to pattern (requires activedirectory module)\n\n`` Get-ADComputer -Filter \"Name -like 'PC-*'\" | Select-String -Pattern PC-\\d+``\n\n#### Get all computer names\n\n``Get-ADComputer -Filter * | Select-Object -ExpandProperty Name``\n\n#### Get computer last logon\n\n```\nGet-ADComputer -Filter * -Properties Name,OperatingSystem ,lastlogontimestamp | Select Name,OperatingSystem ,@{N='lastlogontimestamp'; E={[DateTime]::FromFileTime($_.lastlogontimestamp)}}\n```\n\n#### Get current logged on user\n\n`` query user /server:$SERVER``\n\n#### Get LastLogonDate/LastLogon for each computer\n\n```\nGet-ADComputer -Filter * -Properties * | Sort LastLogon | Select Name, LastLogonDate,@{Name='LastLogon';Expression={[DateTime]::FromFileTime($_.LastLogon)}}\n```\n\n#### Get All Disabled Users (Excluding OU)\n\n``Search-ADAccount -AccountDisabled -UsersOnly | Where {$_.DistinguishedName -notlike \"*OU=Disabled Users,OU=USERS,DC=EXAMPLE,DC=COM\"}``\n\n#### Get LastLogon for User\n\n``Get-ADUser -Identity “username” -Properties “LastLogonDate”``\n\n#### Enable Hyper-V\n\n``Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All``\n\n#### Toggle SMBv1\n\n``Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force``\n\n#### Enable script execution\n\n``powershell.exe Set-ExecutionPolicy Bypass -Force``\n\n#### Retrieve Inventory of Installed Applications on remote computer (requires winget)\n\n`Invoke-Command -ComputerName COMPUTER-01 -ScriptBlock { winget list}`\n\n#### Scheduled Reboot\n\n`shutdown -r -t $([int]([datetime]\"11PM\"-(Get-Date)).TotalSeconds)`\n\n#### Restart Explorer\n\n```\ngps explorer | spps\n```\n\n#### WAC and PowerShell Remote Management\n\n```\nGet-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private\nEnable-PSRemoting -force\n```\n\n#### Time Sync\n\n```\nw32tm /query /status\nw32tm /config /manualpeerlist:\"time.google.com,time.cloudflare.com,time.windows.com\" /syncfromflags:manual /reliable:YES /update\nRestart-Service w32time\nw32tm /resync\n```\n\n## Snippets\n\n#### Reset Windows Update\n\n```powershell\n# Stop Windows Update Services\nWrite-Host \"Stopping Windows Update Services...\"\nStop-Service -Name wuauserv -Force -ErrorAction SilentlyContinue\nStop-Service -Name cryptSvc -Force -ErrorAction SilentlyContinue\nStop-Service -Name bits -Force -ErrorAction SilentlyContinue\nStop-Service -Name msiserver -Force -ErrorAction SilentlyContinue\n\n# Rename SoftwareDistribution and Catroot2 Folders\nWrite-Host \"Renaming SoftwareDistribution and Catroot2 Folders...\"\nRename-Item -Path \"C:\\Windows\\SoftwareDistribution\" -NewName \"SoftwareDistribution.old\" -ErrorAction SilentlyContinue\nRename-Item -Path \"C:\\Windows\\System32\\catroot2\" -NewName \"catroot2.old\" -ErrorAction SilentlyContinue\n\n# Re-register Windows Update DLLs\nWrite-Host \"Re-registering Windows Update DLLs...\"\n$Dlls = @(\n    \"atl.dll\", \"urlmon.dll\", \"mshtml.dll\", \"shdocvw.dll\", \"browseui.dll\",\n    \"jscript.dll\", \"vbscript.dll\", \"scrrun.dll\", \"msxml.dll\", \"msxml3.dll\",\n    \"msxml6.dll\", \"actxprxy.dll\", \"softpub.dll\", \"wintrust.dll\", \"dssenh.dll\",\n    \"rsaenh.dll\", \"gpkcsp.dll\", \"sccbase.dll\", \"slbcsp.dll\", \"cryptdlg.dll\",\n    \"oleaut32.dll\", \"ole32.dll\", \"shell32.dll\", \"initpki.dll\", \"wuapi.dll\",\n    \"wuaueng.dll\", \"wucltui.dll\", \"wups.dll\", \"wups2.dll\", \"wuweb.dll\",\n    \"qmgr.dll\", \"qmgrprxy.dll\", \"wucltux.dll\", \"muweb.dll\", \"wuwebv.dll\"\n)\n\nforeach ($Dll in $Dlls) {\n    Try {\n        regsvr32.exe /s \"C:\\Windows\\System32\\$Dll\"\n        Write-Host \"Registered $Dll\"\n    } Catch {\n        Write-Warning \"Failed to register $Dll\"\n    }\n}\n\n# Reset Winsock\nWrite-Host \"Resetting Winsock...\"\nnetsh winsock reset\n\n# Restart Windows Update Services\nWrite-Host \"Restarting Windows Update Services...\"\nStart-Service -Name wuauserv -ErrorAction SilentlyContinue\nStart-Service -Name cryptSvc -ErrorAction SilentlyContinue\nStart-Service -Name bits -ErrorAction SilentlyContinue\nStart-Service -Name msiserver -ErrorAction SilentlyContinue\n\nWrite-Host \"Windows Update reset complete. You may need to restart your computer.\"\n```\n\n#### Inventory collection script (Logon script that pushes system info to share)\n\n```powershell\n$filename = Join-Path -Path \\\\server-name\\IT-Inventory\\ -ChildPath \"${env:COMPUTERNAME}.txt\"\n\n\nGet-ComputerInfo | \n    Select-Object CsName, CsManufacturer, CsModel, BiosSeralNumber, CsProcessors, CsPhyicallyInstalledMemory, OsName, OsVersion, CsUserName |\n    Sort-Object |\n    out-file -FilePath $filename\n```\n\n```powershell\n# Get the current directory\n$currentDirectory = Get-Location\n\n# Define the output CSV file name\n$outputCsv = \"$currentDirectory\\output.csv\"\n\n# Initialize an empty array to store the data\n$dataArray = @()\n\n# Loop through each file in the current directory\nGet-ChildItem -Path $currentDirectory -File | ForEach-Object {\n    $file = $_.FullName\n\n    # Read the file contents\n    $content = Get-Content -Path $file\n\n    # Create a hashtable to store the data for each file\n    $dataHash = @{}\n  \n    # Parse each line and extract key-value pairs\n    foreach ($line in $content) {\n        if ($line -match \"^(.*)\\s+:\\s+(.*)$\") {\n            $key = $matches[1].Trim()\n            $value = $matches[2].Trim()\n\n            # Add the key-value pair to the hashtable\n            $dataHash[$key] = $value\n        }\n    }\n\n    # Convert the hashtable to a custom object and add to the data array\n    $dataArray += New-Object PSObject -Property $dataHash\n}\n\n# Define the custom column headers\n$columnHeaders = @{\n    \"CsName\" = \"Computer Name\"\n    \"CsManufacturer\" = \"Manufacturer\"\n    \"CsModel\" = \"Model\"\n    \"BiosSeralNumber\" = \"BIOS Serial Number\"\n    \"CsProcessors\" = \"Processor\"\n    \"CsPhyicallyInstalledMemory\" = \"Physical Memory (Bytes)\"\n    \"OsName\" = \"Operating System\"\n    \"OsVersion\" = \"OS Version\"\n    \"CsUserName\" = \"User Name\"\n}\n\n# Create a new array with custom headers\n$customDataArray = $dataArray | Select-Object @{Name='Computer Name';Expression={$_.CsName}},\n                                                @{Name='Manufacturer';Expression={$_.CsManufacturer}},\n                                                @{Name='Model';Expression={$_.CsModel}},\n                                                @{Name='BIOS Serial Number';Expression={$_.BiosSeralNumber}},\n                                                @{Name='Processor';Expression={$_.CsProcessors}},\n                                                @{Name='Physical Memory (Bytes)';Expression={$_.CsPhyicallyInstalledMemory}},\n                                                @{Name='Operating System';Expression={$_.OsName}},\n                                                @{Name='OS Version';Expression={$_.OsVersion}},\n                                                @{Name='User Name';Expression={$_.CsUserName}}\n\n# Export the data to a CSV file\n$customDataArray | Export-Csv -Path $outputCsv -NoTypeInformation\n```\n\n#### Dump all Bitlocker IDs and Recovery Keys from Active Directory\n\n```powershell\n\nImport-Module ActiveDirectory\n\n$computers = Get-ADComputer -Filter * -Property Name | ForEach-Object {\n    $recoveryKeys = Get-ADObject -Filter 'objectclass -eq \"msFVE-RecoveryInformation\"' -SearchBase $_.DistinguishedName -Properties 'msFVE-RecoveryPassword'\n    foreach ($key in $recoveryKeys) {\n        [PSCustomObject]@{\n            ComputerName = $_.Name\n            RecoveryKeyID = $key.Name\n            RecoveryPassword = $key.'msFVE-RecoveryPassword'\n        }\n    }\n}\n\n$computers | Format-Table -AutoSize\n```\n\n#### Batch convert HEIC to JPG (Requires ImageMagick)\n\n```powershell\nAdd-Type -AssemblyName System.Windows.Forms\nAdd-Type -AssemblyName System.Drawing\n\nfunction Select-FolderDialog {\n    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog\n    $folderBrowser.Description = \"Select the folder containing HEIC images\"\n    $result = $folderBrowser.ShowDialog()\n    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {\n        return $folderBrowser.SelectedPath\n    }\n    return $null\n}\n\nfunction Select-SaveFileDialog {\n    $saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog\n    $saveFileDialog.Filter = \"PDF files (*.pdf)|*.pdf\"\n    $saveFileDialog.Title = \"Save PDF As\"\n    $saveFileDialog.DefaultExt = \"pdf\"\n    $result = $saveFileDialog.ShowDialog()\n    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {\n        return $saveFileDialog.FileName\n    }\n    return $null\n}\n\nfunction Convert-HEICtoPDF {\n    [System.Windows.Forms.Application]::EnableVisualStyles()\n\n    $inputDir = Select-FolderDialog\n    if (-not $inputDir) {\n        [System.Windows.Forms.MessageBox]::Show(\"No folder selected. Exiting.\")\n        return\n    }\n\n    $outputPdf = Select-SaveFileDialog\n    if (-not $outputPdf) {\n        [System.Windows.Forms.MessageBox]::Show(\"No output file selected. Exiting.\")\n        return\n    }\n\n    $heicFiles = Get-ChildItem -Path $inputDir -Filter *.heic\n    if ($heicFiles.Count -eq 0) {\n        [System.Windows.Forms.MessageBox]::Show(\"No HEIC files found in the directory.\")\n        return\n    }\n\n    foreach ($file in $heicFiles) {\n        $jpgFile = [System.IO.Path]::ChangeExtension($file.FullName, \".jpg\")\n        \u0026 magick \"$($file.FullName)\" \"$jpgFile\"\n    }\n\n    $jpgFiles = Get-ChildItem -Path $inputDir -Filter *.jpg\n    \u0026 magick convert $jpgFiles.FullName $outputPdf\n\n    [System.Windows.Forms.MessageBox]::Show(\"PDF created successfully at $outputPdf\")\n}\n\nConvert-HEICtoPDF\n```\n\n#### Push Updates to Remote Computers using Invoke-WuJob (PSWindowsUpdate)\n\n```powershell\n$Computers = @(\"PC01\",\"PM04\",\"PC06\",\"PC08\",\"PC-JOAN\",\"PC-SARA\",\"LAWOFFICE-2\",\"PC03\",\"PC07\")\n$OnlineComputers = @()\n\nforeach ($Computer in $Computers) {\n    if (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {\n        $OnlineComputers += $Computer\n    }\n    else {\n        Write-Host \"$Computer is offline.\"\n    }\n}\n\nInvoke-WuJob -ComputerName $OnlineComputers -Script { \n    ipmo PSWindowsUpdate; \n    Install-WindowsUpdate -AcceptAll -IgnoreReboot -MicrosoftUpdate | Out-File \"C:\\Windows\\PSWindowsUpdate.log\"\n} -RunNow -Confirm:$false -Verbose -ErrorAction Ignore\n```\n\n#### Self-elevate script\n\n```powershell\nif (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {\n if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {\n  $CommandLine = \"-File `\"\" + $MyInvocation.MyCommand.Path + \"`\" \" + $MyInvocation.UnboundArguments\n  Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine\n  Exit\n }\n}\n```\n\n#### Get logged in users for each computer\n\n```powershell\n$COMPUTER_LIST = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name\n\nforeach ($COMPUTER in $COMPUTER_LIST) {\necho [$COMPUTER]\nquery user /server:$COMPUTER\necho `n\n}\n```\n\n#### Update PATH Environment Variable Dynamically\n\nPortable tools and programs are placed in a directory, loops over the directory and adds subfolders to PATH environment variable if they don't already exist.\n\n```powershell\n$binPath = \"C:\\bin\"\nGet-ChildItem -Path $binPath -Directory | ForEach-Object {\n    $currentPath = [System.Environment]::GetEnvironmentVariable(\"PATH\", \"Machine\")\n    $newPath = $_.FullName\n    If (-Not $currentPath.Contains($newPath)) {\n        [System.Environment]::SetEnvironmentVariable(\"PATH\", \"$currentPath;$newPath\", \"Machine\")\n    }\n}\n```\n\n#### Schedule Reboot\n\n```powershell\n$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -command \"\u0026 {Restart-Computer -Force -wait}\"'\n$trigger = New-ScheduledTaskTrigger -Once -At 3am\n$taskname = 'ScheduledReboot'\n\n$params = @{\nAction  = $action\nTrigger = $trigger\nTaskName = $taskname\n}\n\n    if(Get-ScheduledTask -TaskName $params.TaskName -EA SilentlyContinue) { \n        Set-ScheduledTask @params\n     }\n    else {\n        Register-ScheduledTask @params\n    }\n```\n\n#### Toggle touch screen\n\n```powershell\n$TouchScreenDevices = Get-PnpDevice | Where-Object { $_.FriendlyName -like \"*HID-compliant touch screen*\" }\n\nforeach ($Device in $TouchScreenDevices) {\n    if ($Device.Status -eq 'OK') {\n        Write-Output \"Disabling device: $($Device.FriendlyName)...\"\n        Disable-PnpDevice -InstanceId $Device.InstanceId -Confirm:$false\n    } else {\n        Write-Output \"Enabling device: $($Device.FriendlyName)...\"\n        Enable-PnpDevice -InstanceId $Device.InstanceId -Confirm:$false\n    }\n}\n```\n\n#### List all installed software via Registry keys\n\n```powershell\n$registryPaths = @(\n    \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\",\n    \"HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\"\n)\n\n\n$installedSoftware = Get-ItemProperty -Path $registryPaths |\n    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |\n    Where-Object { $_.DisplayName -and $_.DisplayName -ne \"\" } |\n    Sort-Object DisplayName\n\n\n$installedSoftware\n```\n\n#### Get REG key of any installed program\n\n```powershell\n$keys = dir HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall | where { $_.GetValueNames() -contains 'DisplayName' }\n$keys += dir HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall | where { $_.GetValueNames() -contains 'DisplayName' }\n \n$k = $keys | where { $_.GetValue('DisplayName') -eq 'DISPLAYNAMEHERE' }\n```\n\n#### Do maintenance\n\n**Requires PatchMyPC**\n\n```powershell\n# Windows Update\nif ((Get-Module -ListAvailable -Name PSWindowsUpdate) -eq $null)\n{\n    Write-Host -ForegroundColor Yellow \"Windows Update module not found, installing...\"\n    Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force\n    Install-Module -Name PSWindowsUpdate -Force\n}\n\nWrite-Host -ForegroundColor Yellow \"Getting Windows Updates...\"\nImport-Module PSWindowsUpdate\nInstall-WindowsUpdate -AcceptAll -IgnoreReboot\n\n# Patch Software\nWrite-Host -ForegroundColor Yellow \"Patching installed software...\"\n\u0026 C:\\Users\\ITAdmin\\Downloads\\PatchMyPC.exe /auto -Wait\n\n# System File Check\nsfc /scannow\n\n# Cleanup disk\ncleanmgr.exe /full\n```\n\n#### File organizer\n\n```powershell\n# PowerShell script to organize files into subdirectories based on file type, without moving existing directories\n# ! Use with caution there is no confirmation or undo !\n\n# Prompt user to enter the directory path\n$directoryPath = Read-Host -Prompt 'Enter the directory path'\n\n# Check if the directory exists\nif (-Not (Test-Path $directoryPath)) {\n    Write-Host \"The directory does not exist.\"\n    exit\n}\n\n# Define subdirectory names and file extensions\n$subdirectories = @{\n    \"Photos\" = @(\"*.jpg\", \"*.jpeg\", \"*.png\", \"*.gif\", \"*.bmp\", \"*.tiff\");\n    \"Videos\" = @(\"*.mp4\", \"*.mov\", \"*.wmv\", \"*.flv\", \"*.avi\", \"*.mkv\");\n    \"Documents\" = @(\"*.doc\", \"*.docx\", \"*.pdf\", \"*.txt\", \"*.xls\", \"*.xlsx\", \"*.ppt\", \"*.pptx\");\n    \"Bin\" = @(\"*.exe\", \"*.bin\", \"*.dll\", \"*.bat\", \"*.msi\");\n    \"Other\" = @()\n}\n\n# Function to move files to their respective subdirectories\nfunction Move-Files {\n    param(\n        [string]$SubDir,\n        [string[]]$Extensions\n    )\n\n    # Create the subdirectory if it doesn't exist\n    $subDirPath = Join-Path $directoryPath $SubDir\n    if (-Not (Test-Path $subDirPath)) {\n        New-Item -Path $subDirPath -ItemType Directory | Out-Null\n    }\n\n    # Move files to the subdirectory\n    foreach ($extension in $Extensions) {\n        Get-ChildItem -Path $directoryPath -Filter $extension -File | Move-Item -Destination $subDirPath\n    }\n}\n\n# Move files based on extensions\nforeach ($subDir in $subdirectories.Keys) {\n    Move-Files -SubDir $subDir -Extensions $subdirectories[$subDir]\n}\n\n# Move remaining files to 'Other' directory\nGet-ChildItem -Path $directoryPath -File | \n    Where-Object { $_.Extension -notin $subdirectories.Values -and !($_.PSIsContainer) } | \n    Move-Item -Destination (Join-Path $directoryPath \"Other\")\n```\n\n#### Dump Wireless Password For All Profiles\n\n```powershell\n$profiles = (netsh wlan show profiles) | Select-String \"\\:(.+)$\" | %{$_.Matches.Groups[1].Value.Trim()}\n\nforeach ($profile in $profiles) {\n\n    # Get details about the profile, including the password in clear text\n    $password = (netsh wlan show profile name=$profile key=clear) | Select-String \"Key Content\\W+\\:(.+)$\" | %{$_.Matches.Groups[1].Value.Trim()}\n\n    # Print the profile name and password\n    \"SSID: $profile\"\n    \"Password: $password\"\n    \"-------------------------\"\n}\n```\n\n#### Winget Bulk Install\n\nhttps://winstall.app\n\n```powershell\nwinget install --id=Microsoft.DotNet.Framework.DeveloperPack_4 -e  ; winget install --id=Google.Chrome -e  ; winget install --id=Microsoft.VCRedist.2013.x64 -e  ; winget install --id=Microsoft.VCRedist.2013.x86 -e  ; winget install --id=Microsoft.VCRedist.2015+.x64 -e  ; winget install --id=Microsoft.VCRedist.2015+.x86 -e  ; winget install --id=Microsoft.VCRedist.2012.x64 -e  ; winget install --id=Microsoft.VCRedist.2012.x86 -e  ; winget install --id=Microsoft.VCRedist.2010.x64 -e  ; winget install --id=Microsoft.VCRedist.2010.x86 -e  ; winget install --id=Microsoft.VCRedist.2005.x86 -e  ; winget install --id=Microsoft.VCRedist.2008.x86 -e  ; winget install --id=Microsoft.VCRedist.2008.x64 -e  ; winget install --id=Oracle.JavaRuntimeEnvironment -e  ; winget install --id=7zip.7zip -e  ; winget install --id=Adobe.Acrobat.Reader.64-bit -e \n```\n\n#### Install and configure Windows Subsystem for Linux (Server 2019)\n\n```powershell\nEnable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux\n\ncurl.exe -L -o debian.appx https://aka.ms/wsl-debian-gnulinux\nRename-Item .\\debian.appx debian.zip\nExpand-Archive .\\debian.zip debian\nExpand-Archive .\\debian\\DistroLauncher-Appx_1.12.1.0_x64.appx\n.\\debian\\DistroLauncher-Appx_1.12.1.0_x64\\debian.exe\n```\n\n#### List Mapped Network Printers with IP Address\n\n```powershell\n$printers = Get-WmiObject -Query \"SELECT * FROM Win32_Printer\"\nforeach ($printer in $printers) {\n    $portName = $printer.PortName\n    $port = Get-WmiObject -Query \"SELECT * FROM Win32_TCPIPPrinterPort WHERE Name = '$portName'\"\n    if ($port -ne $null) {\n        [PSCustomObject]@{\n            PrinterName = $printer.Name\n            IPAddress = $port.HostAddress\n        }\n    }\n}\n```\n\n## Active Directory\n\n```\nImport-Module ActiveDirectory\n```\n\n#### Locate all DCs\n\n```powershell\ndig +noall +answer _ldap._tcp.dc._msdcs.\u003cdomain-name\u003e SRV\n```\n\n```powershell\nnslookup -type=srv _ldap._tcp.dc._msdcs.\u003cdomain-name\u003e\n```\n\n```powershell\nnltest /dclist:\u003cyour-domain-name\u003e\n```\n\n```powershell\nGet-ADDomainController -Filter * | Select Name, HostName, Site\n```\n\n#### Disable all stale computer accounts (90 days)\n\n```powershell\n# Import the Active Directory module\nImport-Module ActiveDirectory\n\n# Define the number of days for stale account detection\n$StaleDays = 90\n\n# Calculate the date from $StaleDays ago\n$Date = (Get-Date).AddDays(-$StaleDays)\n\n# Find computer accounts that haven't logged in since $Date\n$StaleComputers = Get-ADComputer -Filter {LastLogonTimeStamp -lt $Date} -Properties LastLogonTimeStamp\n\n# Loop through each stale computer and remove it\nforeach ($Computer in $StaleComputers) {\n    $ComputerName = $Computer.Name\n    $LastLogonDate = [datetime]::FromFileTime($Computer.LastLogonTimeStamp)\n  \n    Write-Host \"Removing computer: $ComputerName (Last Logon: $LastLogonDate)\"\n  \n    # Remove the computer account from Active Directory\n    # Uncomment the next line to perform the deletion\n    # Remove-ADComputer -Identity $Computer.DistinguishedName -Confirm:$false\n}\n\n# Output completion message\nWrite-Host \"Completed removal of stale computer accounts.\"\n```\n\n#### Retrieve list of all DCs and assigned FSMO roles\n\n```\nImport-Module ActiveDirectory\n\n\n$DCs = Get-ADDomainController -Filter *\n\nforeach ($DC in $DCs) {\n    $roles = @()\n\n    $forest = Get-ADForest\n    if ($DC.HostName -eq $forest.SchemaMaster) { $roles += \"Schema Master\" }\n    if ($DC.HostName -eq $forest.DomainNamingMaster) { $roles += \"Domain Naming Master\" }\n\n    $domain = Get-ADDomain\n    if ($DC.HostName -eq $domain.RIDMaster) { $roles += \"RID Master\" }\n    if ($DC.HostName -eq $domain.InfrastructureMaster) { $roles += \"Infrastructure Master\" }\n    if ($DC.HostName -eq $domain.PDCEmulator) { $roles += \"PDC Emulator\" }\n\n    [PSCustomObject]@{\n        DomainController = $DC.HostName\n        Roles = $roles -join ', '\n    }\n}\n```\n\n## Microsoft 365\n\n#### Connect to Exchange Online\n\n```\nInstall-Module -Name ExchangeOnlineManagement\nImport-Module ExchangeOnlineManagement\nConnect-ExchangeOnline -UserPrincipalName \u003cUPN\u003e [-ExchangeEnvironmentName \u003cValue\u003e] [-ShowBanner:$false] [-DelegatedOrganization \u003cString\u003e] [-SkipLoadingFormatData]\n```\n\n#### Exchange Online MailBox info (Mailbox size and Archive size)\n\n```powershell\nGet-Mailbox -RecipientTypeDetails UserMailbox | ForEach-Object {\n    $mailboxStats = Get-MailboxStatistics $_.Identity\n    $archiveStats = @{TotalItemSize = \"N/A\"}  # Default value in case there's no archive.\n    if ($_.ArchiveStatus -eq 'Active') {\n        $archiveStats = Get-MailboxStatistics $_.Identity -Archive\n    }\n    [PSCustomObject]@{\n        DisplayName = $_.DisplayName\n        PrimarySmtpAddress = $_.PrimarySmtpAddress\n        ArchiveStatus = $_.ArchiveStatus\n        AutoExpandArchive = $_.AutoExpandingArchiveEnabled\n        TotalItemSize = $mailboxStats.TotalItemSize\n        ArchiveSize = if ($_.ArchiveStatus -eq 'Active') {$archiveStats.TotalItemSize} else {\"Not Applicable\"}\n    }\n} | Select-Object DisplayName, PrimarySmtpAddress, ArchiveStatus, AutoExpandArchive, TotalItemSize, ArchiveSize\n```\n\n## Scripts\n\n* [HP Bloatware Removal](https://gist.github.com/mark05e/a79221b4245962a477a49eb281d97388) (varied results)\n* [AD Audit](https://github.com/phillips321/adaudit)\n* [Microsoft Official Windows Search Reset](https://www.microsoft.com/en-us/download/details.aspx?id=100295)\n* PSCmder (Really bad PDQ alternative, script and `commands.txt` are in this repo. Usefull for remote installation or command exec)\n* [CIS Critical Controls](https://github.com/robvandenbrink/Critical-Controls-v7)\n\n## Windows Defender\n\n[Windows Defender is enough, if you harden it](https://gist.github.com/superswan/1d6ed59e75273f90a481428964be3ae5)\n\n## Fun\n\n#### Final Fantasy Victory Beep\n\n```\n[console]::beep(784,300); Start-Sleep -Milliseconds 100; [console]::beep(784,600); [console]::beep(622,600); [console]::beep(698,600); [console]::beep(784,200); Start-Sleep -Milliseconds 200; [console]::beep(698,200); [console]::beep(784,800)\n```\n\n#### DVD Cursor\n\nBounces cursor around the screen like the DVD logo\n\n```\nAdd-Type -AssemblyName System.Windows.Forms\n\n# Get screen dimensions\n$bounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds\n$maxX = $bounds.Width\n$maxY = $bounds.Height\n\n$x = [System.Windows.Forms.Cursor]::Position.X\n$y = [System.Windows.Forms.Cursor]::Position.Y\n\n# Movement vector (speed)\n$dx = 14\n$dy = 14\n\nwhile ($true) {\n    $x += $dx\n    $y += $dy\n\n    # Check for screen bounds and reverse direction if needed\n    if ($x -le 0 -or $x -ge $maxX) {\n        $dx = -$dx\n    }\n    if ($y -le 0 -or $y -ge $maxY) {\n        $dy = -$dy\n    }\n\n    [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($x, $y)\n  \n    Start-Sleep -Milliseconds 50\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperswan%2Fpowershell-sysadmin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuperswan%2Fpowershell-sysadmin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperswan%2Fpowershell-sysadmin/lists"}