Helpful Power Shell Scripts
Table of Contents
Get PS version
To get the version of powershell we use the command $PSVersionTable.PSVersion.
PS C:\Users\62> $PSVersionTable
Name Value
---- -----
PSVersion 7.4.0
PSEdition Core
GitCommitId 7.4.0
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Get List of users in an AD Group
Extract AD Group Members and export the results in a CSV file.
Get-ADGroupMember -Identity GRP_M365_F1_Users | Select-Object name, objectClass,distinguishedName,AccountExpirationDate | Export-CSV -Path “.\adgroupmembers.csv”
Note – This has a limit of 5000 records being added to CSV.
The Get-ADGroupMember has the object limit, once it goes over 5000, it stops processing.
Get All AD Users in an AD Group – Export to file
# Look up performed in the group "GRP_m365_F1_Users" for all users
# Import Active Directory module
Import-Module ActiveDirectory
# Define the name of the AD group
$groupName = "GRP_m365_F1_Users"
# Define the path of the output CSV file
$outputPath = "C:\temp\grp_m365_F1_Users.csv"
# Get the distinguished name of the group
$groupDn = (Get-ADGroup $groupName).DistinguishedName
# Get the members of the AD group
$groupMembers = Get-ADUser -Filter "memberOf -eq '$groupDn'" -Properties DisplayName, UserPrincipalName
# Initialize an array to store the user details
$userDetails = @()
# Loop through the group members
foreach($user in $groupMembers)
{
# Create a PSObject to store the user details
$userObj = New-Object PSObject
$userObj | Add-Member -MemberType NoteProperty -Name "sAMAccountName" -Value $user.SamAccountName
$userObj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $user.DisplayName
$userObj | Add-Member -MemberType NoteProperty -Name "UserPrincipalName" -Value $user.UserPrincipalName
# Add the user object to the array
$userDetails += $userObj
}
# Export the user details to a CSV file
$userDetails | Export-Csv -Path $outputPath -NoTypeInformation
Get All Expired users in an AD Group
# Look up performed in the group "sec_m365_F1_Users" for expired users
# Import Active Directory module
Import-Module ActiveDirectory
# Define the name of the AD group
$groupName = "sec_m365_F1_Users"
# Define the path of the output CSV file
$outputPath = "C:\temp\removable_sec_m365_F1_Users.csv"
# Get the distinguished name of the group
$groupDn = (Get-ADGroup $groupName).DistinguishedName
# Get the members of the AD group
$groupMembers = Get-ADUser -Filter "memberOf -eq '$groupDn'" -Properties DisplayName, UserPrincipalName, AccountExpirationDate
# Initialize an array to store the details of removed users
$expiredUserDetails = @()
# Loop through the group members
foreach ($user in $groupMembers) {
# Check if the user's account is expired
if ($user.AccountExpirationDate -and ($user.AccountExpirationDate -lt (Get-Date))) {
# Create a PSObject to store the user details
$userObj = New-Object PSObject
$userObj | Add-Member -MemberType NoteProperty -Name "sAMAccountName" -Value $user.SamAccountName
$userObj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $user.DisplayName
$userObj | Add-Member -MemberType NoteProperty -Name "UserPrincipalName" -Value $user.UserPrincipalName
$userObj | Add-Member -MemberType NoteProperty -Name "AccountExpirationDate" -Value $user.AccountExpirationDate
# Add the user object to the array
$expiredUserDetails += $userObj
# Remove the user from the group
#Remove-ADGroupMember -Identity $groupName -Members $user -Confirm:$false
}
}
# Export the details of removed users to a CSV file
$expiredUserDetails | Export-Csv -Path $outputPath -NoTypeInformation
Get all verb commands
Get-Verb
List all commands
Get-Commands
Search Commands using verbs
Get-commands –verb get*
This will list all commands which contain with the verb "Get"
e.g.
Cmdlet Get-TypeData
Cmdlet Get-UICulture
Cmdlet Get-Unique
Cmdlet Get-Uptime
Cmdlet Get-UsageAggregates
Cmdlet Get-Variable
Cmdlet Get-Verb
Search commands using nouns
Get-commands –Noun file*
This will list all commands which contain the noun "file".
e.g.
CommandType Name
----------- ----
Function Export-File
Cmdlet Get-FileHash
Cmdlet Out-File
Cmdlet Unblock-File
Create a new file in PS
New-Item "file_name.ps1"
Open a file in PS and read it
Code "file_name.ps1"
Get all current PS profiles in windows machine
PS C:\Users\62> $profile | Select-Object *
AllUsersAllHosts : C:\Program Files\PowerShell\7\profile.ps1
AllUsersCurrentHost : C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1
CurrentUserAllHosts : C:\Users\62\Documents\PowerShell\profile.ps1
CurrentUserCurrentHost : C:\Users\62\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
Length : 69
Execute a PS1 from terminal
./file_name.ps1
Get BIOS information of a specific PC
Get-WmiObject -Class win32_bios -ComputerName CLAITSADM008
In case Get-WmiObjects is not recognized as a cmdlet, function. Use Get-CimInstance
PS C:\Users\62> Get-CimInstance -computername cladteadm006 -Class win32_bios
SMBIOSBIOSVersion : N3EET25W (1.11 )
Manufacturer : LENOVO
Name : N3EET25W (1.11 )
SerialNumber : PF*****B
Version : LENOVO - 1110
PSComputerName : ABCDEFGHIJK006
Get BIOS information of all PC’s in a domain
Get-WmiObject -class win21_bios -ComputerName (Get-ADComputer -Filter * | select -ExpandProperty name)
- This works in PS version 2.0
For PS version 3.0 we can use - [Get-WmiObject -class win32_bios -ComputerName (Get-ADComputer -Filter *).name]
Connect Remotely to Another Device using PS
I am using PC-A and there is a PC-B.
I am running PS in PC-A and I want to run a few commands in PC-B without opening the PC-B or remoting to it.
In order to achieve this we will open the PS session in PC-A and run command
C:\users\1234>Enter-PSSession –computerName PC-B
Remotely check the logs from a remote device
Invoke-Command -ComputerName HOSTNAME {Get-EventLog -LogName System -new 3}
NOTE - -new 3 means get the newest 3 log entries
Note – If we need to perform the lookup on multiple devices at once, just add the comma separated device name.
Invoke-Command -ComputerName HOSTNAME001,HOSTNAME009,HOSTNAME010 {Get-EventLog -LogName System -new 3}
Restart a computer remotely
Invoke-Command –ComputerName HOST008 {restart-computer -Force}
Search an AD Group
Get-ADGroup -Filter "name -like '*Medipath*'" | Select-Object name
Search AD Group Members
Get-ADGroupMember -Identity 'App_XenApp_Medipath_GUI_VHH_Test' | Select-Object name
Get ad groups associated with a user
Get-ADPrincipalGroupMembership -Identity username_of_user
Run Commands on a Remote Computer
Enter-PSSession –ComputerName HOST010
It allows connect to a remote PC using powershell and execute further commands as per user requirement.
Get GUID of all apps installed on a machine
GUID of all installed apps is available in registry, we can initially check which all apps are installed on the PC under these 2 registry paths
- HKEY_LOCAL_MACHINE:\Software\Microsoft\Windows\CurrentVersion\Uninstall
- HKEY_LOCAL_MACHINE:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
We can get the names of all these installed app using
Get-ChildItem -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' | select name
- In some results we can see that the GUID is specified, but in some the GUID is not specified.
- We can fetch the GUID for each installed software using the following 2 ways:
/** Option A - Performing a lookup in each registry and fetching the GUID for each app **/
$UninstallKeys = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" $null = New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS $UninstallKeys += Get-ChildItem HKU: -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | ForEach-Object { "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" }
foreach ($UninstallKey in $UninstallKeys) { Get-ChildItem -Path $UninstallKey -ErrorAction SilentlyContinue | Where {$_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$'} | Select-Object @{n='GUID';e={$_.PSChildName}}, @{n='Name'; e={$_.GetValue('DisplayName')}} }
/** Option B - Create a function to fetch both GUID and Installed_App_Name List **/
function Get-InstalledSoftware { <# .SYNOPSIS Retrieves a list of all software installed .EXAMPLE Get-InstalledSoftware This example retrieves all software installed on the local computer .PARAMETER Name The software title you'd like to limit the query to. #> [OutputType([System.Management.Automation.PSObject])] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Name ) $UninstallKeys = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" $null = New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS $UninstallKeys += Get-ChildItem HKU: -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | ForEach-Object { "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" } if (-not $UninstallKeys) { Write-Verbose -Message 'No software registry keys found' } else { foreach ($UninstallKey in $UninstallKeys) { if ($PSBoundParameters.ContainsKey('Name')) { $WhereBlock = { ($_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$') -and ($_.GetValue('DisplayName') -like "$Name*") } } else { $WhereBlock = { ($_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$') -and ($_.GetValue('DisplayName')) } } $gciParams = @{ Path = $UninstallKey ErrorAction = 'SilentlyContinue' } $selectProperties = @( @{n='GUID'; e={$_.PSChildName}}, @{n='Name'; e={$_.GetValue('DisplayName')}} ) Get-ChildItem @gciParams | Where $WhereBlock | Select-Object -Property $selectProperties } } }
Fetch the GUID of msi installed on the local machine
Get-WmiObject WIN32_PRODUCT |Format-Table IDENTIFYINGNUMBER,NAME
Fetch the GUID of a specific msi installed on the local machine
Get-WmiObject WIN32_PRODUCT | Where Name –eq 'Citrix Studio'| Format-Table IDENTIFYINGNUMBER,NAME
Can also be manually accessed in regedit on path
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Check services on a remote computer
Invoke-command –computername HOST009 {get-services –name powertoys}
Getting event logs from a remote pc, sorting the results using time and selecting the specific columns to be listed
Invoke-Command -comp HOST009 {Get-EventLog -LogName System -new 3} | sort timewritten |Format-Table -Property timewritten,index,message –AutoSize
Get List of installed software’s on a remote PC
Get-WmiObject -Class Win32_Product -Computer RemoteComputerName | Select-Object Name, Version,vendor
Note – If you need to search a specific software installed on the remote device, use –
Get-WmiObject -Class win32_product -ComputerName RemoteComputerName | Select-Object name,version,vendor |Where-Object -FilterScript {$_.Name -like "Brother*"}
We can also use the Where-object using –Property to filter using name
Get-WmiObject -Class win32_product -ComputerName RemoteComputerName | Select-Object name,version,vendor | Where-Object -Property Name -Like '*google*'
Another e.g.
Get-WmiObject -Class win32_product -ComputerName RemoteComputerName | Select-Object name, vendor,version | Where-Object Name -Like '*Visual Studi*'
Another way, if apps are deployed using an end point solution like SCCM – connect to remote device powershell and execute the following query to search a specific app using appname –
Get-CimInstance -query "select * from sms_installedsoftware where productname like 'Ready%'" -Namespace "root\CIMV2\SMS"
Select specific columns
Get-CimInstance -ComputerName HOSTNAME -Query "select * from sms_installedsoftware" -Namespace "root\CIMV2\sms" | Select-Object productname,productversion,publisher,installdate
Another e.g.
Get-CimInstance -ComputerName HOSTNAME -Query "select * from sms_installedsoftware" -Namespace "root\CIMV2\sms" | Select-Object productname,productversion,publisher,installdate | where-object productname –Like '*microsoft*'