Home

Powershell

This is a selection of scripts and code snippets I have collected while working in IT Support. I've tried to provide attriubtions where possible, but some of these are old and sources could not be found.

It should go without saying that you should test these carefully before running them in production environments, please don't blame me if something you copied from the internet breaks something that matters to you.

Getting Started

A few resources to help the eager beginner:

Remote Powershell

The following snippets will help you enable PSRemoting, run remote commands and remote sessions. You need to be an administrator to use this.

Start by enabling Remote Powershell. If you have access to the machine, run the following:

Enable-PSremoting

https://4sysops.com/wiki/enable-powershell-remoting/

Use the following to run a single command, inserting the command you wish to run on the remote computer instead of Your Code.

invoke-command -computername Target -scriptblock{Your Code}

Below is a practical example, if you want to mess with your colleague by killing Outlook:

invoke-command -Computername Petes-PC -scriptblock{taskkill /IM Outlook.exe /F}

Or really mess with your colleague by restarting their computer:

invoke-command -Computername Petes-PC -scriptblock{shutdown /r /t 00}

Invoke-Command

Alternatively, start a remote session, giving you the ability to run multiple commands one after the other:

New-PSSession -computername computername

You can leave the session and leave it running, ready to reconnect to it later:

Disconnect-PSSession

Create a named session:

New-PSSession -computername Computername -name SessionName

List currently running sessions:

Get-PSSession

Reconnect to a specific session:

Connect-PSSession -id 2

Or:

Connect-PSSession -name SessionName

Or end the session:

Exit-PSSession

Use this to create a temporary session that ends when you exit:

Enter-PSSession

New-PSSession

Disconnect-PSSession

Get-PSSession

Connect-PSSession

Exit-PSSession

Enter-PSSession

Writing to Files

Saving command output and session output can be useful for debugging and checking things worked correctly.

The most simple solution is out-file.

get-childitem c:\scripts|out-file c:\scripts\output.txt

For logging an entire Powershell session use start-transcript

Start-Transcript -Path "C:\transcripts\transcript0.txt"
stop-transcript

start-transcript

out-file

Sending Email with Powershell

Emailing log files to yourself is an easy way to check scheduled scripts are working correctly

Gmail:

$secpasswd = ConvertTo-SecureString YourPassword -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential (YourGmailAddress, $secpasswd)
$From = "YourGmail"
$To = "DestinationAddress"
$Attachment = "c:\scripts\file.txt"
$Subject = "Subject"
$Body = "Body"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $mycreds -Attachments $Attachment

Office 365:

$secpasswd = ConvertTo-SecureString YourPassword -AsPlainText -Force
$userid = New-Object System.Management.Automation.PSCredential (Your365Address, $secpasswd)
$mycreds=Get-Credential $userid
$From = "Your365Address"
$To = "DestinationAddress"
$Attachment = "c:\scripts\file.txt"
$Subject = "Subject"
$Body = "Body"
$SMTPServer = "amtp.office365.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $mycreds -Attachments $Attachment

Send-MailMessage

Get a list of All Hyper-V VMs

Get a list of all the VMs on the current server:

Get-VM

Get details about a sepcific VM

Get-VM -VMName VmName

Get VM's on a sepcific server:

Get-VM -Computername Hyper-VServer

Get VM's in a failover cluster:

Get-ClusterGroup | ? {$_.GroupType -eq 'VirtualMachine' } | Get-VM

Get VMs based on a partial name match, replace SRV with the name of your VM/VMs:

get-vm|where-object -property name -like "*SRV-*"

Get all VM's and power them on:

$vms = get-vm
Foreach ($vm in $VMs){Start-VM $vm}

Get all VM's and run a command within the guest Windows OS:

$vms = get-vm
$credential = Get-Credential
Foreach ($VM in $VMs)
{
Start-VM $vm
}
start-sleep -s 60
foreach($vm in $vms){
Invoke-Command -VMName $vm.name -ScriptBlock {YourCommand}
} -Credential $credential
}

Get the provisioned size of each VM's VHD and the actual size..

Get-VM | ForEach { $Vm = $_; $_.HardDrives } | ForEach {
    $GetVhd = Get-VHD -Path $_.Path
    [pscustomobject]@{
        Vm = $Vm.Name
        Name = $_.Name
        Type = $GetVhd.VhdType
        ProvisionedGB = ($GetVhd.Size / 1GB)
        CommittedGB = ($GetVhd.FileSize / 1GB)
    }
}

Get the Integration Services Version of each VM in a cluster.

$clusterNodes = Get-ClusterNode;
ForEach($item in $clusterNodes)
{Get-VM -ComputerName $item.Name | ft Name,IntegrationServicesVersion | out-file c:\temp\intservices.txt}

Get-VM

Get-ClusterGroup

Stack Overflow: How to Get Actual Hard Disk Memory of A VM?

Get the Last Reboot Reason

$after = (get-date).adddays(-55) #55 day limit so we dont get too many results
Get-WinEvent -ea SilentlyContinue -ComputerName localhost -FilterHashtable @{LogName = "System"; StartTime = $after; id=1074}|fl

Test Connectivity

Check you can ping a computer:

test-netconnection -computername ComputerName

Check you can connect to a computer on a specific port:

test-netconnection -port 80 -computername ComputerName

Take a list of IPs from a CSV, test RDP connectivity to each IP

import-csv -path c:\temp\ips.csv | foreach-object{
$return = test-netconnection -computername $_.IPS -commontcpport rdp
if ($return.TcpTestsucceeded){echo "True" $_.IPS}else{}
}

Test-Netconnection

Delete Old User Profiles

Delete all user profiles, except those marked as Special, that haven't been used within the last 7 days:

Get-WMIObject -class Win32_UserProfile | Where {
(!$_.Special) -and ($_.ConvertToDateTime($_.LastDownloadTime) -lt (Get-Date).AddDays(-7))
}|remove-wmiobject

https://community.spiceworks.com/how_to/124316-delete-user-profiles-with-powershell

Get All User Sessions on All Servers in Active Directory

This will list all the users logged in to all the servers found in Active Directory:

Import-Module ActiveDirectory
$Servers = Get-ADComputer -Filter {OperatingSystem -like "*server*"}
$SessionList
ForEach ($Server in $Servers) {
$ServerName = $Server.Name
Write-Host "Querying $ServerName"
echo $servername
$queryResults = (qwinsta /server:$ServerName | foreach { (($_.trim() -replace "\s+",","))} | ConvertFrom-Csv) 
ForEach ($queryResult in $queryResults) {
    $RDPUser = $queryResult.USERNAME
    $sessionType = $queryResult.SESSIONNAME
	If (($RDPUser -match "[a-z]") -and ($RDPUser -ne $NULL)) { 
	Write-Host $ServerName logged in by $RDPUser on $sessionType
    $SessionList = $SessionList + "`n`n" + $ServerName + " logged in by " + $RDPUser + " on " + $sessionType
    }
    }
}
$SessionList

https://github.com/chrisdee/Scripts/blob/master/PowerShell/Working/TerminalService/GetActiveTerminalServiceRDPSessions.ps1

Remotely Enable Remote Desktop

We've all been in that position, you've just deployed a new server somewhere and forgotten to enable remote desktop. This will get that sorted for you.

Save the code below to a .bat file, I called mine remoteon.bat:

@echo off
setlocal
if {%1}=={} goto syntax
:loop
if {%1}=={} goto finish
set remote="\\%1\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server"
shift
reg.exe ADD %remote% /v fDenyTSConnections /t REG_DWORD /d 0 /f>nul 2>&1
if NOT %ERRORLEVEL% EQU 0 @echo %remote% NOT found.
goto loop
:syntax
@echo Syntax: RemoteDesktop Computer1 [Computer2 .... Computern]
goto loop
:finish
endlocal

Use it like this:

remoteon.bat computername
remoteon.bat computername computername computername

Ping Loop

Ping something, until you stop it, log it to a text file and add a date after every 50 pings...

@echo off
:loop
echo %date% %time% >>ping.txt
echo pinging..
for %%x in (50) do (
ping 8.8.8.8 -n %%x >> ping.txt
)
goto loop

Am I Virtual?

the following command will return something like "Microsoft" or "VMWare" if you're in a VM:

wmic baseboard get manufacturer,product

Create an Administrator

To create a new Administrator user from the command prompt:

net user username password /ADD
net localgroup administrators username /add

https://ss64.com/nt/net-useradmin.html