Active Directory Users and Computers (ADUC) - see RSAT
assoc command – associate a file extension with a command– see also ftype command
the assoc
command doesn't work directly from within PowerShell.
Instead, prefix with cmd
. So, for example with PHP:
cmd /c assoc .php=phpfile
followed with
cmd /c ftype phpfile="C:\php8_2\php.exe" -f "%1" -- %~2
you can also put in the following to your profile
function
assoc
{cmd /c assoc
$args}
function
ftype
{cmd /c ftype
$args}
Install-Module -Name AudioDeviceCmdlets
show defaults
Get-AudioDevice -List | ? {$_.DefaultCommunication -eq $true} | select ID, Type, Name
background color, get
(Get-Host ).UI.RawUI.BackgroundColor
background color, set
$a = (Get-Host).UI.RawUI
$a.BackgroundColor = "DarkGreen"
There aren’t too many choices
[Enum]::GetValues([ConsoleColor])
only lists 16 color choices
certs, list
Get-ChildItem -Recurse Cert: | ft
command, run remotely - see remote command
compress a file - see zip a file
computer name see also environment variables
$env:computername
with fully qualified domain name
[System.Net.Dns]::GetHostByName($env:computerName)
computer remote session, - see remote session, initiate
computer serial number - see PC, get serial number
copy files from one directory to another
$destination
=
"D:\xml\"
$location
=
"D:\Client Portal\"
function
processCopy
{
$files
=
Get-ChildItem
-Path:$location
foreach($file
in
$files)
{
$path = $file.FullName
if($file.Name
-ne
"copy.ps1"){
Copy-Item
-Path:$path
-Destination:$destination
-Force -Confirm:$false
Write-Host
"Item"
$file.Name
" has been sucessfully copied to"
$destination
}
if($file.Attributes
-eq
"Directory")
{
copyFile $file
$destination
}
}
}
function
copyFile($directory,
$target)
{
$target
+=
$directory.Name
$files
=
Get-ChildItem
-Path:$directory.FullName
foreach($file
in
$files)
{
$path
=
$file.FullName
if($file.Name
-ne
"copy.ps1"){
Copy-Item
-Path:$path
-Destination:$target
-Force -Confirm:$false
Write-Host
"Item"
$file.Name
" has been sucessfully copied to"
$target
}
if($file.Attributes
-eq
"Directory")
copyFile
$file
$target
}
}
function
Pause
($Message="Press any key to continue...")
{
Write-Host
-NoNewLine
$Message
$null
=
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host
""
}
#main
processCopy
Pause
Count how many files in a directory, excluding "bin" and "obj" files & directories
(gci "D:\VisualStudio\GID_CRM" -exclude bin, obj -Recurse).Count
top 20 threads (filtering out totals) shows
gwmi
Win32_PerfFormattedData_PerfProc_Thread |
?{$_.Name -notmatch '_Total'} |
sort PercentProcessorTime -desc |
select -first 20 |
ft -auto Name,IDProcess,IDThread,PercentProcessorTime
date of files, determine
ls d:\filemaker -rec | foreach {$_.creationtime -lt "02/25/2013"}
date of most recent file in a directory
$latest
=
Get-ChildItem
-Path
$backedUpDirectoryPath
|
Sort-Object
LastWriteTime -Descending |
Select-Object
-First
1
$latest.name
$latest.LastWriteTime
directory, loop through
$sourceDirectory= "D:\somedirectory"
ls
$sourceDirectory
-rec |
foreach
{
$filename
=
$_.Name
$length
=
$_.length
$creationtime
=
$_.creationtime
$DirectoryName
=
$_.Directory.Name
Write-Host
$i
$filename
", "
$DirectoryName
", "
$length
", "
$creationtime
$i++
}
delete file
Remove-Item $a[$i] -recurse -force
directory, delete certain subdirectories and everything underneath them
gci $workingDirectory -include bin, obj, Upload -Recurse -Force | Remove-Item -Recurse -Force
In Powershell 3.0, it is simpler:
dir -Directory
#List only directories
dir -File
#List only files
Or to limit to just 2 directories deep:
dir -Directory .\*\*
In PowerShell 2, to just get directories (with grouping):
Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Or to limit to just 2 directories deep:
Get-ChildItem .\*\* | ?{ $_.PSIsContainer }
To get a raw list of directories, without the grouping:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName
(gci -Force "C:\Users\gollum\myPrecious\odes" -Recurse -ErrorAction SilentlyContinue | measure Length -s).sum
or in Gb
(gci -Force "C:\Users\gollum\myPrecious\odes" -Recurse -ErrorAction SilentlyContinue | measure Length -s).sum 1Gb
get-psdrive c | % {$_.free/($_.used + $_.free)} | % tostring p
disk space consumed by a bunch of similarly-named files, percentage of disk space
How much space are our SQL server error logs consuming on the F drive?
$errorFileLogLocation
=
"F:\Microsoft
SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log"
"{0:P}"
-f ((gci $errorFileLogLocation
Errorlog* | measure Length -s).sum / (Get-PSDrive
F |
%
{($_.used
+
$_.free)}))
disk drives, status of all – including free disk space
$props
=
@(
'DriveLetter'
'FileSystemLabel'
'FileSystem'
'DriveType'
'HealthStatus'
'OperationalStatus'
@{Name
=
'SizeRemaining'
Expression
= {"{0:N3} Gb"
-f ($_.SizeRemaining/
1Gb)}}
@{Name
=
'Size'
Expression
= {"{0:N3} Gb"
-f ($_.Size
/
1Gb)}}
@{Name
=
'% Free'
Expression
= {"{0:P}"
-f ($_.SizeRemaining
/
$_.Size)}}
)
Get-Volume
-DriveLetter C |
Select-Object
$props
| ogv
$smtpFrom = "fromEmail@yourDomain"
$smtpTo ="toEmail@yourDomain"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpTo
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = $body
$smtpServer = "yourTenant-com01ec.mail.protection.outlook.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$ credentials =new-object system.net.networkcredential("whosSending@yourDomain","TopSecret")
$smtp.credentials=$credentials.getCredential($smtpServer,"25","basic")
$smtp.Send($message)
This does not work all the time
send-mailmessage -to
"user@mydomain.com" `
-from
"user@mydomain.com" `
-subject
"sample subject line" `
-smtpServer
mymailserver.mydomain.com `
-body
'test body'
not only does it not work, putting in a "try-catch" block doesn't give you an error; it errors out right away when you first try to run.
event log -
Get-WinEvent -FilterHashtable @{logname = "Application"; starttime = '11/14/22 07:40 am'; endtime = '11/14/22 07:55 am'} | ? {$_.LevelDisplayName -eq 'Error' -or $_.LevelDisplayName -eq 'Warning'}
or
Get-EventLog -LogName 'Application' | Select TimeWritten, Message, EventID | Where-Object -FilterScript {$_.TimeWritten -ge '11/14/22 07:40 am' -and $_.TimeWritten -le '11/14/22 07:55 am'}
file, append data
$logFile
=
"C:\Logs\LogFile.txt"
Add-Content
$logFile
"a new line"
file, folder exist?
if
(Test-Path
C:\Scripts)
{
if
(Test-Path
C:\Scripts\Test.txt)
{
"Folder and file exist"
}
else
{
"Folder exists, file doesn't"
}
}
else
{
"Folder does not exist"
}
fonts, install
$path
=
"directoryContainingFontFiles"
$shell
=
New-Object
-ComObject Shell.Application
$shell.Namespace($path).Items().InvokeVerbEx("Install")
Or, if you want to check to see if the target PC already has it:
$sourcPath
=
"\\genetic-id.com\share\Dept_Shares\IT\Museo Sans
Rounded\OpenType CFF Std"
$destinationPath
=
"c:\windows\fonts\"
$fontFileSource
=
Get-ChildItem
$sourcPath | Select Name
# Check for presence of each file. If any ONE of the 6 files
are missing, install ALL of them.
foreach
($file
in
$fontFileSource)
{
If
(Test-Path
"$($destinationPath)$($File.name)")
{
#"font $($File.name) found, no action necessary"
}
else
{
#"font $($File.name) not found, need to add"
$shell = New-Object -ComObject Shell.Application
$shell.Namespace($sourcPath).Items().InvokeVerbEx("Install")
break
}
}
If you want to deploy these fonts across your organization, then invoke this from Group Policy.
ftype command – associate a file extension with a command – see also assoc command
the assoc
command doesn't work directly from within PowerShell.
Instead, prefix with cmd
. So, for example with PHP:
cmd /c ftype phpfile="C:\php8_2\php.exe" -f "%1" -- %~2
installed programs
The only reason I include the PSPath - which is quite lengthy & often useless - is because for some entries just about all the other fields are empty. I think these are mainly OS update entries.
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName,InstallLocation,DisplayVersion,PSPath,Publisher,InstallDate | ogv
language
for the machine you're on
Get-WinSystemLocale
What languages are available on the machine?
Get-WinUserLanguageList | ft
MAC addresses for a PC
getmac
My Documents location
$mydocs = [ environment]::getfolderpath("mydocuments")
change directory to my documents
$dir = [environment]::getfolderpath("mydocuments")
cd $dir
or if you don't want to mess with a variable and want to embed date/time in a file name
Get-AdUser | Export-Csv -Path "$([environment]::getfolderpath("mydocuments"))\fileBaseName$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv" -NoTypeInformation -Encoding UTF8
name of the PC/server you're on right now
$env:COMPUTERNAME
or
$Get-WmiObject Win32_Computersystem).name
open files
all the open files in a certain directory
Get-SmbOpenFile | Where-Object -Property Path -Like "*somePath*" | ft ClientUserName,Path
or
Get-SmbOpenFile | Where-Object -Property ShareRelativePath -Match "someString" | select ShareRelativePath | fl
supposedly, this will find open files on another server
Get-SmbOpenFile -ScopeName "someServer"
but this always fails for me
Get-SmbOpenFile : No MSFT_SMBOpenFile objects found with property 'ScopeName' equal to 'someServer'. Verify the value of the property and retry.
path environment variable
$env:Path -split(";") | sort $_
to add:
$Env:PATH += ";C:\php8_2"
to remove:
$Remove
=
'C:\php8_2'
$env:Path
= ($env:Path.Split(';') |
?
-FilterScript {$_
-ne
$Remove}) -join
';'
gwmi win32_bios
remote
$sessionOption
=
New-CimSessionOption
-Protocol Dcom
$cimSession
=
new-cimsession
-sessionOption
$sessionOption
-computername somePCName
Get-CimInstance
Win32_BIOS -CimSession
$cimSession
pc name - see name of the PC/server you're on right now
processes, how many are going on
(Get-Process).Count
process, is one particular process active?
process, kill one particular process
profile location - $profile
To create a whole new profile (it checks first to make sure we don't already have one):
if (!(test-path $profile)) {new-item -type file -path $profile -force}
Prompt, change - helpful to include this in scripts that connect to other servers
function global:prompt{
$promptString
=
"US $($executionContext.SessionState.Path.CurrentLocation)
$([datetime]::Now.ToLongTimeString())>"
write-host
-NoNewLine -ForegroundColor Cyan
$promptString
return
" "
}
#change prompt
prompt
That global: up top is pretty important
Get-Service RemoteRegistry
Enable:
Set-Service –Name RemoteRegistry –Computer someComputer -StartupType Automatic
Get-Service RemoteRegistry -ComputerName someComputer | Start-Service
registry values for a key, read and display
$Srv
=
"PC_Name"
$key
=
"SOFTWARE\Microsoft\Windows\CurrentVersion"
$type
= [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey
= [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type
,
$Srv)
$regKey
=
$regKey.OpenSubKey($key)
Write-Host
"Values"
Write-Host
"------"
Foreach($val
in
$regKey.GetValueNames()){
Write-Host
$val.PadRight(30) -nonewline
Write-Host
$regKey.GetValue("$val")
}
Note that the way you specify which of the topmost hives
(HKEY_LOCAL_MACHINE
in this case) is by the
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
on several different computers at once:
$Cred
=
Get-Credential
Invoke-Command
-ComputerName Mordor,
TheShire {Get-Service
-Name W32time}
-Credential
$Cred
runs on the remote computer and the results are returned to your local computer as deserialized objects. That doesn't mean you can't start or stop a service using a method with Invoke-Command though. It just means that the method has to be called in the remote session.
Invoke-Command -ComputerName Mordor, TheShire {(Get-Service -Name W32time).Stop()} - Credential $Cred
Sometimes a simple command…
Invoke-Command -ComputerName 12.25.10.13{$env:COMPUTERNAME} -Credential $Cred
…fails with:
[12.25.10.13] Connecting to remote server 12.25.10.13 failed with
the following error message : The WinRM client cannot process the request.
Default authentication may be used with an IP address under the following
conditions: the transport is HTTPS or the destination is in the TrustedHosts
list, and explicit credentials are provided. Use winrm.cmd to configure
TrustedHosts. Note that computers in the TrustedHosts list might not be
authenticated. For more information on how to set TrustedHosts run the
following command: winrm help config. For more information, see the
about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (129.255.108.136:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : CannotUseIPAddress,PSSessionStateBroken
Trying to fix with…
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 12.25.10.13 -Force
…fails with:
Set-Item : Access is denied.
At line:1 char:1
+ Set-Item WSMan:\localhost\Client\TrustedHosts -Value 12.25.10.13 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified:
(:) [Set-Item], InvalidOperation
Exception
+ FullyQualifiedErrorId :
System.InvalidOperationException,Microsoft.PowerShell.Commands.SetItemCommand
$Cred
=
Get-Credential
Enter-PSSession
-ComputerName MagicKindom
-Credential
$Cred
to end:
Exit-PSSession
RSAT (e.g., ADUC)
What available modules are installed?
Get-WindowsCapability -online | ? Name -like Rsat* | ft
Install RSAT for Windows 10 1809 and 1903 automated
reg add
"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Servicing"
/v RepairContentServerSource /d
2
/t REG_DWORD /f
Add-WindowsCapability
-online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Add-WindowsCapability
-online -Name Rsat.Dns.Tools~~~~0.0.1.0
Add-WindowsCapability
-Online -Name Rsat.FileServices.Tools~~~~0.0.1.0
Add-WindowsCapability
-Online -Name Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0
Add-WindowsCapability
-Online -Name Rsat.DHCP.Tools~~~~0.0.1.0
Add-WindowsCapability
-Online -Name Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0
Add-WindowsCapability
-Online -Name Rsat.WSUS.Tools~~~~0.0.1.0
Schedule PowerShell Scripts (in Server 2008)
In the "Action" tab, for the "Start a program",
need to have "powershell" for the "Program/script"
and the file location for the "Add arguments (optional)".
If you're attempting to run some commands - like
New-Object
IO.FileSystemWatcher
then you must precede the file name with
"-NoExit .
" (including the dot).
serial number for a PC - see PC, get serial number
Find if you don't know the exact name but have some idea of the name. For example: you know the service has something to do with the word, profile:
get-service | Where-Object {$_.DisplayName -like "*profile*"} | ft
session, kill existing
Get-PSSession | Remove-PSSession
session, remote initiate - see remote session, initiate
shared directories for a server, list
get-WmiObject -class Win32_Share -computer someServer
task scheduler, run a powershell script in
in the "Actions" tab, in the "Start a program" area, put in "powershell"
In the "Add arguments" area, put in "-ExecutionPolicy Bypass D:\path\YourPowerShellScript.ps1"
If you see, "This task requires that the user account specified has Log on as batch job rights" the user must be able to do the following
- Start -> Run
- Type in secpol.msc /s
- Select "Local Policies" in MSC snap in
- Select "User Rights Assignment"
- Right click on "Log on as batch job" and select Properties
- Click "Add User or Group", and include the relevant user.
tenant, which one am I on?
Get-MsolAccountSku
The command above returns a list of SKUs, each of which includes an AccountSkuID
field. The first part of this each of the AccountSkuID
field
on every row in this list of SKUs has the tenant name.
If you just want the tenant name all by itself, use this instead:
(Get-MsolAccountSku)[0].AccountSkuId.split(":")[0]
which looks at the AccountSkuID
field of the first SKU in the array
and then uses the portion before the colon.
UNC directory, change to
Set-Location \\yourDomain.com\share
updates, windows - see windows updates
user profiles
Get-WmiObject
-Class
Win32_UserProfile
-ComputerName
Windows Services - see Services
$Session
=
New-Object
-ComObject Microsoft.Update.Session
$Searcher
=
$Session.CreateUpdateSearcher()
$HistoryCount
=
$Searcher.GetTotalHistoryCount()
$Searcher.QueryHistory(0,$HistoryCount)
|
ForEach-Object {$_}
or try
gwmi -cl win32_reliabilityRecords | select ProductName, SourceName, TimeGenerated, EventIdentifier, Reco0rdNumber, __CLASS | ft
or
gwmi win32_quickfixengineering |sort installedon -desc | ft
Windows version - the single-line commands below will return various aspects
(Get-WmiObject Win32_OperatingSystem).Version
# short number e.g., 10.0.18363
[environment]::OSVersion.Version
# same info as above but in table form
Get-CimInstance
Win32_OperatingSystem
# table with more entries including serial number and system directory
Get-WindowsEdition
-Online
# edition e.g., Core
gwmi win32_operatingsystem |
%
caption
# plain English version e.g., Microsoft Windows 10 Home
(gwmi win32_operatingsystem).caption
# plain English version e.g., Microsoft Windows 10 Home
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem")
$src_folder
=
"D:\project"
$destfile
=
"D:\project.zip"
$compressionLevel
= [System.IO.Compression.CompressionLevel]::Optimal
$includeBaseDir
=
$false
[System.IO.Compression.ZipFile]::CreateFromDirectory($src_folder,
$destfile,
$compressionLevel,
$includeBaseDir)