PowerShell #
Version & Help #
# List PowerShell version
$PSVersionTable
# Clear screen
clear # or
Strg + l
# Update Help Files
update-help
# List Examples (for Get-WmiObject)
get-help Get-WmiObject -examples
# Browser Version
get-help Get-WmiObject -online
Execution Policies #
List current execution policy which determines the level of security that is applied to scripts:
Get-ExecutionPolicy # Retrieve current execution policy
Get-ExecutionPolicy -List # List all execution policys on the system
Set execution policy examples:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
The execution policy definitions:
Restricted
: No scripts are allowed to run. (Default)
AllSigned
: Only scripts signed by a trusted publisher are allowed to run.
RemoteSigned
: Local scripts can run without a signature, downloaded or remote scripts must be signed by a trusted publisher.
Unrestricted
: All scripts can run regardless their origin or whether they are signed.
Bypass
: No execution policy is enforced. All scripts can run, and no warnings or prompts are displayed.
Scope:
CurrentUser
: The execution policy set for the current user account.
LocalMachine
: The execution policy set for the entire machine.
Process
: The current execution policy for the current PowerShell process.
Domain & WorkGroup #
The join or leave a Domain provide the Credentials of a Domain User with the necessary privileges.
# Join Domain (ask for Credentials)
Add-Computer -DomainName "jklug.work" -Credential (Get-Credential) -Restart
# Join Domain (provide Credentials without PW)
Add-Computer -DomainName 'jklug.work' -Credential "Administrator" -Restart
# Join Workgroup (provide Credentials without PW)
Add-Computer -WorkGroupName "WORKGROUP" -Credential "Administrator" -Restart
User, Domain & PC Details #
# List WorkGroup
(Get-WmiObject -Class Win32_ComputerSystem).Workgroup
# Check if in Domain
(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
# Domain\User
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
# Domain
$env:UserDomain
# User
$env:UserName
# Path to User profile
$env:USERPROFILE
# Computer Name
$env:ComputerName
# OS and Hardware Details
systeminfo
# System Information Utility
msinfo32
# Display Windows Version
winver
# Rretrieve Hyper-V Settings
Get-ComputerInfo -property "HyperV*"
# Processor
Get-WmiObject win32_processor
# BIOS Version
Get-WmiObject win32_bios
Shell Credentials #
Open a Shell with different credentials:
# Run PS with different credentials
runas /user:Domain\Username powershell
# Run CMD with different credentials
runas /user:Domain\Username cmd
# Example
runas /user:JKLUG\Administrator powershell
Run Scripts #
C:\scripts\script.ps1 |
Run PS Script full path |
.\script.ps1 |
Invoke from folder |
# Run script from shortcut:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File "C:\scripts\script.ps1"
# Run script from shortcut, define EP:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "C:\scripts\script.ps1"
MD5 & SHA-256 Checksum #
# Generate MD5 Checksum of a file
Get-FileHash -Path C:\path\to\file -Algorithm MD5
# Generate MD5 Checksum of a file: Same folder
Get-FileHash -Path .\file -Algorithm MD5
# Shell Output:
Algorithm Hash Path
--------- ---- ----
MD5 6DC33DF9E4A089A39E5E3A4E1932DE67 C:\file
# Generate SHA-256 Checksum of a file
Get-FileHash -Path C:\path\to\your\file.ext -Algorithm SHA256
# Shell Output:
Algorithm Hash Path
--------- ---- ----
SHA256 F4BAAA8135E0F9A993F0258A4D095DB475096896BD3ADB48369F1F70C1F0D9D4 C:\file
PS Remote Management #
Enable Windows Remote Management via GP:
"Computer Configuration" -> "Policies" -> "Administrative Templates" -> "Windows Components" -> "Windows Remote Management (WinRM)"
Enable Windows Remote Management manually:
Enable-PSRemoting -Force
Check if service is running:
Get-Service WinRM
Start service:
Start-Service WinRM
Remote Session #
Start remote PS session:
Enter-PSSession -ComputerName Hostname
Start remote PS session (with specific credentials):
Enter-PSSession -ComputerName Hostname -Credential Domain\User
Exit remote PS session:
exit
Start only Session without entering:
New-PSSession -ComputerName jkw-w10-01
Shell output / List sessions:
Get-PSSession
Id Name ComputerName ComputerType State ConfigurationName Availability
-- ---- ------------ ------------ ----- ----------------- ------------
10 WinRM10 jkw-w10-01 RemoteMachine Opened Microsoft.PowerShell Available
Enter PS session:
Enter-PSSession -Id 10
or etsn -Id 10
Close PS session:
Remove-PSSession -Id 10
Invoke Command #
Invoke Command (without session):
Invoke-Command -ComputerName jkw-w10-01 -ScriptBlock {
# PS Command 1
# PS Command 2 ...
}
Invoke Command with specific credentials:
Invoke-Command -ComputerName jkw-w10-01 -Credential Domain\Username -ScriptBlock {
# PS Command 1
# PS Command 2 ...
}
Copy From & To Session #
Copy files and folders from Remote Session:
# Create Session
$session = New-PSSession -ComputerName jkw-w10-01
# Copy file
Copy-Item -Path C:\tmp\file.txt -Destination C:\tmp -FromSession $session
# Copy folder
Copy-Item -Path C:\tmp\folder -Destination C:\tmp -Recurse -FromSession $session
Copy files and folders to Remote Session:
# Create Session
$session = New-PSSession -ComputerName jkw-w10-01
# Copy file
Copy-Item -Path C:\tmp\file.txt -Destination C:\tmp -ToSession $session
# Copy folder
Copy-Item -Path C:\tmp\folder -Destination C:\tmp -Recurse -ToSession $session
Active Directory #
User SID #
# List SID of AD user
Get-ADUser -Identity "username" | Select-Object SID
USER GUID #
- Find GUID for user name
$username = 'juergen.klug' # Define username
$user = Get-ADUser -Filter "SamAccountName -eq '$username'" -Properties ObjectGUID
if ($user) {
$guid = $user.ObjectGUID.Guid
Write-Host "GUID for $username is: $guid"
} else {
Write-Host "User not found."
}
List username for GUID
$guid = [guid]'3F2504E0-4F89-11D3-9A0C-0305E82C3301' # Define GUID
$guidByteArray = $guid.ToByteArray()
# List SamAccountName
Get-ADUser -Filter {ObjectGUID -eq $guidByteArray} | Select-Object -Property SamAccountName
Users #
# Create new AD user
New-ADUser -Name "Juergen Klug" `
-SamAccountName "juergen.klug" `
-GivenName "Juergen" `
-Surname "Klug" `
-UserPrincipalName "juergen.klug@jklug.work" `
-Enabled $true `
-PasswordNeverExpires $true `
-AccountPassword (ConvertTo-SecureString -AsPlainText "Test123!" -Force) `
-Path "OU=JKW-Group,DC=jklug,DC=work"
# Delete AD user
Remove-ADUser -Identity juergen.klug -Confirm:$false
Groups #
# Create new Group
New-ADGroup -Name "groupname" `
-SamAccountName "groupname" `
-GroupCategory Security `
-GroupScope Global `
-Path "OU=JKW-Group,DC=jklug,DC=work"
# Add Users to Group:
Add-ADGroupMember -Identity groupname -Members user1,user2
# Remove Users from Group:
Remove-ADGroupMember -Identity groupname -Members user1,user2 -Confirm:$false
# Remove all Users from Group:
Get-ADGroupMember groupname | ForEach-Object {Remove-ADGroupMember groupname $_ -Confirm:$false}
Organizational Units #
# Create OU:
New-ADOrganizationalUnit -Name OU1 -Path "DC=jklug,DC=work" -ProtectedFromAccidentalDeletion $False
# Create OU in OU:
New-ADOrganizationalUnit -Name OU2 -Path "OU=OU1,DC=jklug,DC=work" -ProtectedFromAccidentalDeletion $False
# Delete OU:
Remove-ADOrganizationalUnit -Identity "OU=OU1,DC=jklug,DC=work" -Recursive -Confirm:$false
Import Users from CSV #
Example: new-users.csv
firstname,lastname,username,password,email
Juergen,Klug,Juergen.Klug,gU7x!Kp$vJxj,Juergen.Klug@jklug.work
John,Doe,John.Doe,gU7f!Kp$vJxj,John.Doe@jklug.work
# seperate with "," not ";"
# no umlauts
# no "," in password
Powershell Script
# Define Domain Name
$Domain = "jklug.work"
# Define Active Directory Path
$AD_path = "OU=JKW-Users,DC=jklug,DC=work"
# Add Users to Active Directory Group
$AD_group = "JKW-Group"
# CSV Path
$CSV_path = Import-csv C:\scripts\new-users.csv
#Loop through each row containing user details in the CSV file
foreach ($User in $CSV_path)
{
#Read user data from each field in each row and assign the data to a variable as below
$Username = $User.username
$Password = $User.password
$Firstname = $User.firstname
$Lastname = $User.lastname
$email = $User.email
#Check to see if the user already exists in AD
if (Get-ADUser -F {SamAccountName -eq $Username})
{
#If user does exist, give a warning
Write-Warning "A user account with username $Username already exist in Active Directory."
}
else
{
#User does not exist then proceed to create the new user account
New-ADUser `
-Name "$Firstname $Lastname" `
-GivenName $Firstname `
-Surname $Lastname `
-Enabled $True `
-DisplayName $Username `
-SamAccountName $Username `
-UserPrincipalName $Username@$Domain `
-Path $AD_path `
-EmailAddress $email `
-AccountPassword (convertto-securestring $Password -AsPlainText -Force) -ChangePasswordAtLogon $False
# Add User to Grpup
Add-ADGroupMember -Identity $AD_group -Members $Username
# Set Roaming Profile
#Set-ADUser -Identity $Username -ProfilePath \\Path\to\User_Profiles$\%USERNAME%
}
}
GPO #
# Manually update Group Policy
gpupdate /force
# Group Policy Report Summary
gpresult /r
# Group Policy Report from current user
gpresult /h c:\tmp\gpo.html /f # (/f overwirtes file if it already exists)
# Group Policy Report from specific user
gpresult /user "user1" /h c:\tmp\gpo.html /f
# Group Policy Report for computer
gpresult /r /scope computer
#Open Group Policy Report in MMC
rsop.msc
Check Connection to Domain Controller #
Netlogon Service #
Open CMD and run the following command:
# Display the status of the Netlogon service
sc query netlogon
# Shell output
SERVICE_NAME: netlogon
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING # Check the state
(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
Test-ComputerSecureChannel #
Test secure channel between host and domain
# Test the secure channel between the host and its domain
Test-ComputerSecureChannel -Verbose
# Shell Output
VERBOSE: Performing the operation "Test-ComputerSecureChannel" on target "jkw-w10-02".
True
VERBOSE: The secure channel between the local computer and the domain jklug.work is in good condition.
# Test the secure channel between the host and specific DC
Test-ComputerSecureChannel -Server "WindowsServer2022-primary.jklug.work"
# Shell Output
VERBOSE: Performing the operation "Test-ComputerSecureChannel" on target "jkw-w10-02".
True
VERBOSE: The secure channel between the local computer and the domain jklug.work is in good condition.
Check Active Directory Services #
# Check the status of Active Directory services
nltest /dsgetdc:jklug.work
# PowerShell
DC: \\WindowsServer2022-primary.jklug.work
Address: \\192.168.30.10
Dom Guid: cf3995ea-d5f2-43f8-9e41-420f75c8220a
Dom Name: jklug.work
Forest Name: jklug.work
Dc Site Name: Default-First-Site-Name
Our Site Name: Default-First-Site-Name
Flags: PDC GC DS LDAP KDC TIMESERV GTIMESERV WRITABLE DNS_DC DNS_DOMAIN DNS_FOREST CLOSE_SITE FULL_SECR
ET WS DS_8 DS_9 DS_10 KEYLIST
The command completed successfully
Windows #
Local Groups #
List Users
# List Users from LocalGroup: Remote Desktop Users
Get-LocalGroup -SID "S-1-5-32-555" | Get-LocalGroupMember
# List Users from LocalGroup: Administrators
Get-LocalGroup -SID "S-1-5-32-544" | Get-LocalGroupMember
Add User
# Add User to LocalGroup: Remote Desktop Users
Add-LocalGroupMember -SID "S-1-5-32-555" -Member "JKLUG\user1"
# Add User to LocalGroup: Administrators
Add-LocalGroupMember -SID "S-1-5-32-544" -Member "JKLUG\user1"
Remove User
# Remove User from LocalGroup: Remote Desktop Users
Remove-LocalGroupMember -SID "S-1-5-32-555" -Member "JKLUG\user1"
# Remove User from LocalGroup: Administrators
Remove-LocalGroupMember -SID "S-1-5-32-544" -Member "JKLUG\user1"
Find SID from Local Group
# Find SID, for example "docker-users"
(New-Object System.Security.Principal.NTAccount("docker-users")).Translate([System.Security.Principal.SecurityIdentifier]).Value
Keyboard Layouts #
Get-WinUserLanguageList # List available layouts
Set-WinUserLanguageList -LanguageList en-US # Define layout
Set-WinUserLanguageList -LanguageList de-AT, de-DE, en-US # Define list
Optional Features #
# Check if optional feature is installed
Get-WindowsCapability -Online | ? Name -like "openssh*"
# Install Optional feature
Add-WindowsCapability -Online -Name openssh.client
Networking Overview #
# List interfaces configuration
ipconfig
# Ping
ping IP
# Ping continuous
ping -t IP
# Determine route
tracert IP or DNS
# List hostname
hostname
DHCP #
# Release the current DHCP lease
ipconfig /release
# Get new IP from DHCP
ipconfig /renew
DNS #
# Empty DNS resolver cache
ipconfig /flushdns
Define DNS for a specific network interface:
# Define DNS Server
Set-DnsClientServerAddress -InterfaceAlias "Ethernet0" -ServerAddresses ("192.168.30.10")
# Revert DNS Server to automatically via DHCP
Set-DnsClientServerAddress -InterfaceAlias "Ethernet0" -ResetServerAddresses
List Network Interfaces #
The following commands list the physical and virtual network interfaces.
# List network interfaces
Get-NetAdapter
# List network interfaces: Format Output
Get-NetAdapter | Format-List ifIndex, Name, InterfaceDescription
# Shell Output:
ifIndex : 24
Name : Ethernet 2
InterfaceDescription : Realtek PCIe 2.5GbE Family Controller
ifIndex : 18
Name : Ethernet 5
InterfaceDescription : Intel(R) I350 Gigabit Network Connection #2
ifIndex : 15
Name : Ethernet 4
InterfaceDescription : Intel(R) I350 Gigabit Network Connection
List IPv4 and MAC from Interface #
# List IPv4 and MAC address from specific network interface
$ifAlias = 'Ethernet 2' # Define interface alias
Write-Host $(Get-NetIPAddress -InterfaceAlias $ifAlias -AddressFamily IPv4 | Select-Object -ExpandProperty IPAddress)
Write-Host $(Get-NetAdapter -Name $ifAlias | Select-Object -ExpandProperty MacAddress)
List Routing Table #
# List routing tables
Get-NetRoute
# List routing tables: IPv4
Get-NetRoute | Where-Object { $_.AddressFamily -eq "IPv4" }
# List routing tables: Specific interface
Get-NetRoute -InterfaceIndex 24
# List routing tables: Specific interface
Get-NetRoute -InterfaceIndex 24 | Where-Object { $_.AddressFamily -eq "IPv4" }
# List routing tables: Specific interface (Interface Alias)
Get-NetRoute -InterfaceAlias "Ethernet 2"
IPv4 and DefaultGateway #
Define IPv4 address, default gateway and DHCP for a specific network interface:
# Define IPv4 and DefaultGateway / disable DHCP
New-NetIPAddress `
-InterfaceAlias "Ethernet0" `
-IPAddress "192.168.30.220" `
-PrefixLength 24 `
-DefaultGateway "192.168.30.1"
# Remove IPv4 address
Remove-NetIPAddress -InterfaceAlias "Ethernet0" -Confirm:$false
# Remove DefaultGateway
Remove-NetRoute -InterfaceAlias "Ethernet0" -DestinationPrefix "0.0.0.0/0" -Confirm:$false
# Enable DHCP
Set-NetIPInterface -InterfaceAlias "Ethernet0" -Dhcp Enabled
Processes #
List processes:
Get-Process
Start process:
Start-Process "chrome"
Start process (with path):
& "C:\Program Files\Google\Chrome\Application\chrome.exe"
Stop / terminate process:
Get-Process chrome | Stop-Process
Script: Check if process is running / start process
$process = Get-Process -Name "chrome" -ErrorAction SilentlyContinue
if ($process -eq $null) {
Start-Process "chrome"
Write-Host "Chrome has been started."
}
else {
Write-Host "Chrome is already running."
}
Services #
List Services
# List services / sort by status
Get-Service | Sort-Object status | Format-Table -AutoSize
# List services beginning with "s"
Get-Service "s*" | Sort-Object status | Format-Table -AutoSize
# Only running services
Get-Service | Where-Object {$_.status -eq "running"}
# Only stopped services
Get-Service | Where-Object {$_.status -eq "stopped"}
# List Services / Save to .txt
Get-Service| Format-Table -AutoSize | Out-File -FilePath C:\scripts\svc.txt
# List Services / Save to .html
Get-Service | ConvertTo-HTML Name, DisplayName, Status | Set-Content C:\scripts\svc1.html
Start / Stop Services
# Start Service
Start-Service -Name "WSearch" -PassThru
# Restart Service
Restart-Service -Name "WSearch" -PassThru
# Stop Service
Stop-Service -Name "WSearch" -PassThru
# Startup Type: Automatic / Enabled
Set-Service -Name "Spooler" -StartupType "Automatic"
# Startup Type: Disabled
Set-Service -Name "Spooler" -StartupType "Disabled"
# Startup Type: Manual
Set-Service -Name "Spooler" -StartupType "Manual"
## "-PassThru" = Verbose Output
Files and Directories #
Create, Delte & Move #
Directories
# Create directory / subdirectory:
New-Item C:\tmp\dir1 -ItemType directory
# Alias
mkdir C:\tmp\dir1
Files
# Create file
New-Item -Path C:\path\to\file.txt -ItemType File
# Create file & path, overwrite if file already exists
New-Item -Path C:\path\to\file.txt -ItemType File -force
# Write into file
'Hallo 123' | Out-File -FilePath C:\scripts\text.txt
# Write into file (new line)
'Hallo 123' | Out-File -FilePath C:\scripts\text.txt -Append
Copy Alias
# Copy File
cp "c:\dir1\file1.txt" "c:\dir2"
# Copy Directory with content
cp -r "c:\dir1" "c:\dir2"
# Copy content from directory
cp -r "c:\dir1\*" "c:\dir2"
Move Alias
# Move File
mv "c:\dir1\file1.txt" "c:\dir2"
# Move File (Overwrite in Destination)
mv -force "c:\dir1\file1.txt" "c:\dir2"
# Move Folder and it's content
mv "c:\dir1" "c:\dir2"
Remove Alias
# Remove file
rm "c:\dir1\file1.txt"
# Remove Folder and it's content
rm -r "c:\dir1"
Open Files and Directories
# Open file
Start-Process -FilePath .\file.txt -Verb "Edit"
# Open folder in Windows Explorer
Invoke-Item C:\tmp
# or
ii C:\tmp
Find #
# Find file or folder
Get-ChildItem -Path C:\ -Recurse | Where-Object { $_.Name -like "*file1*" }
Shortcuts #
# Create shortcut to file oder folder
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("C:\shortcut.lnk")
$Shortcut.TargetPath = "c:\path\to\target"
$Shortcut.Save()
RoboCopy #
Robust File Copy is a CLI tool in Windows for copying files and directories.
# Copy data
robocopy C:\source C:\destination /COPY:DATSO /E /R:0 /W:0 /MIR /J
# Define log file
robocopy C:\source C:\destination /COPY:DATSO /E /R:0 /W:0 /MIR /J /LOG:C:\robocopy-log.txt
Copy files to remote host (use UNC)
# Copy files and directories from the source folder, but not the source folder itself
robocopy C:\scripts \\host-name\C$\tmp /COPY:DATSO /E /R:0 /W:0 /MIR /J
# Copy files and directories and also source folder
robocopy c:\scripts \\jkw-w10-01\C$\tmp\scripts /COPY:DATSO /E /R:0 /W:0 /MIR /J
# Copy and save log
robocopy c:\scripts \\jkw-w10-01\C$\tmp\scripts `
/COPY:DATSO /E /R:0 /W:0 /MIR /J `
/LOG:"C:\tmp\robocopy-log.log"
Copy files from remote host (use UNC)
## Copy files and directories from the source folder, but not the source folder itself
robocopy \\host-name\C$\scripts c:\tmp /COPY:DATSO /E /R:0 /W:0 /MIR /J
# Copy files and directories and also source folder
robocopy \\host-name\C$\scripts c:\tmp\scripts /COPY:DATSO /E /R:0 /W:0 /MIR /J
Robocopy Parameters
/COPY:DATSO
: Specifies which file properties to copy: Data, Attributes, Timestamps, Security information (NTFS ACLs) & Ownership.
/E
: Copy subdirectories, including empty ones.
/R:0
: Set number of Retries on failed copies to 0.
/W:0
: Sets wait time between retries to 0 seconds. By default, robocopy waits 30 seconds between attempts to copy a file.
/MIR
: Mirror source directory and destination directory / Delete files at the destination if they no longer exist at the source.
/J
: Unbuffered I/O for the file copy. Recommended for very large files / Copying in restart mode is more reliable when copying large files as it can restart the copy process from where it left off in the event of a failure, rather than starting from the beginning again.
ACL Object Permissions #
List & Copy Permissions
# List permissions from Object
get-acl C:\share | fl
# Copy Permissions from on Object to another
get-acl C:\share | Set-Acl C:\share2
Add User or Group Permissions
$Folder = "C:\share"
$User = "JKLUG\user2"
$Rights = "FullControl"
# Get the current ACL
$acl = Get-Acl $Folder
# Create the access rule
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($User, $Rights, "Allow")
# Add the access rule to the ACL
$acl.SetAccessRule($AccessRule)
# Set the new ACL
Set-Acl $Folder $acl
Remove User or Group Permissions
$Folder = "C:\share"
$User = "JKLUG\user2"
# Get the current ACL
$acl = Get-Acl $Folder
# Find the access rules for the user
$AccessRules = $acl.Access | Where-Object { $_.IdentityReference -eq $User }
# Remove the access rules
foreach ($AccessRule in $AccessRules) {
$acl.RemoveAccessRule($accessRule) | Out-Null
}
# Set the new ACL
Set-Acl $Folder $acl
Reset Permissions
# Reset permission from directory and it's files
icacls c:\share /T /Q /C /RESET
# /T: Apply to all subfolders and files recursively
# /Q: Suppress success messages make command quiet
# /C: Continue when errors occur
# /RESET: Replace the ACLs with default ACLs / reset permissions to default
Event Viewer #
# Windows Logs / Application
Get-WinEvent -LogName Application -MaxEvents 10 -FilterXPath "*[System[(Level=1 or Level=2)]]" | Sort-Object -Property TimeCreated -Descending
# Windows Logs / System
Get-WinEvent -LogName System -MaxEvents 10 -FilterXPath "*[System[(Level=1 or Level=2)]]" | Sort-Object -Property TimeCreated -Descending
# Windows Logs / Security (Logon/Logoff, Account Management, Object Access...)
Get-WinEvent -LogName Security -MaxEvents 50 | Sort-Object -Property TimeCreated -Descending
Scheduled Tasks #
The following script creates a new scheduled task that runs a powershell script. If a scheduled task with the same name already exists, it gets deleted.
# Define path to script
$ScriptPath = "C:\scripts\script.ps1"
# Define name of scheduled task
$TaskName = "JKW-1"
# Optional: Define scheduled task description
$Description = "Run PS Script"
# Define task trigger time
$taskTrigger = New-ScheduledTaskTrigger -Daily -At 20:00
# Define task action
$TaskAction = New-ScheduledTaskAction `
-Execute 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' `
-Argument "-ExecutionPolicy Bypass -File $ScriptPath"
# Define task principal highest privileges
$Principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
# Check if task already exists
$CheckTask = Get-ScheduledTask | Where-Object {$_.TaskName -like $TaskName}
if($CheckTask) {
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
Write-Output "Task $TaskName was deleted" }
# Register the scheduled task
Register-ScheduledTask `
-TaskName "\Microsoft\$TaskName" `
-Action $TaskAction `
-Principal $Principal `
-Trigger $TaskTrigger `
-Description $Description
Task Trigger time examples:
# Daily at 20:00
$taskTrigger = New-ScheduledTaskTrigger -Daily -At 20:00
# Once at 20:00
$taskTrigger = New-ScheduledTaskTrigger -Once -At 20:00
# In 2 minutes from now (useful for testing)
$ts = New-TimeSpan -Minutes 2
$time = (get-date) + $ts
$TaskTrigger = New-ScheduledTaskTrigger -Once -At ($time).ToString("HH:mm")
SSH #
# Create SSH Key Pair: RSA, 4096 bit
ssh-keygen -t rsa -b 4096
# Connect to Server
ssh user@IP
# Disconnect from Sercer
exit # or
"Strg" + "d"
Windows Licenses #
Remove License #
Tested on Windows Server 2022.
- Run CMD as Admin
# Uninstall product key
slmgr /upk
# Reboot
# Remove product key from registry
slmgr /cpky
# Reset the Windows activation timers
slmgr /rearm
Install License #
Tested on Windows Server 2022.
- Run PS as Admin
# Install product key
DISM /Online /Set-Edition:ServerStandard /ProductKey:xxxxx-xxxxx-xxxxx-xxxxx-xxxxx /AcceptEula
Useful Scripts #
Random PW #
Create a Random Password:
function Get-RandomCharacters($length, $characters) {
$random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
$private:ofs=""
return [String]$characters[$random]
}
function Scramble-String([string]$inputString){
$characterArray = $inputString.ToCharArray()
$scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length
$outputString = -join $scrambledStringArray
return $outputString
}
$password = Get-RandomCharacters -length 4 -characters 'abcdefghiklmnoprstuvwxyz'
$password += Get-RandomCharacters -length 4 -characters 'ABCDEFGHKLMNOPRSTUVWXYZ'
$password += Get-RandomCharacters -length 2 -characters '1234567890'
$password += Get-RandomCharacters -length 2 -characters '!$'
$password = Scramble-String $password
Write-Host $password
Remove spaces from string #
$string = " ABC 123 x y z 45 6"
$newstring = $string -replace('\s', '')
Write-Host $newstring
Troubleshooting #
System File Checker (SFC) #
# scan all protected system files / repair any issues (Run PS as administrator)
sfc /scannow