Powershell
Tips and Tricks
Updated: 02 October 2023
Modify Prompt
Based on this
Open Powershell and type
1notepad $profile
If the file does not exist you will be asked to create it, then paste the following
1function prompt {2 $p = Split-Path -leaf -path (Get-Location)3 "$p > "4}
You can replace the $p >
part with anything you’d like to be displayed in your shell
Alternatively, if you would like to see the full path, and the command on the next line you can use
1function prompt {2 $p = Get-Location3 "$p4>"5}
Adding Aliases
Based on this
We can add persistent aliases in our profile by defining functions for them, we can open our Powershell Profile
1notepad $profile
Then we can define a function to navigate to our Repo directory by adding the following to the profile
1function repo {2 set-location c:\Users\NabeelValley\Documents\DevEx\Repos3}
View File Tree
You can view the folder and file tree in powershell using the tree
command.
To view the Folders only in the current directory:
1tree
Which will output something like:
1C:.2└───main
Or from another directory you can use:
1tree ./path/to/dir
To refer to the current directory you can use
tree
without any directory, ortree .
to refer to the current directory. Both ways are almost identical in terms of the output. Note that including the directory in the command results in the full directory path being written in the command’s output
And to view the tree with files included, you can use:
1tree /f
Which will output something like:
1C:.2└───main3 data.txt
And for another directory:
1tree ./path/to/dir /f
Symlinks
Support for
mklink
only exists on newer versions of Windows, otherwise you may need to useNew-Item
Creating symlinks can be done with the mklink
command which is an alias for the New-Item -ItemType SymbolicLink
command
Using the base New-Item
version, a symlink can be created with the below command where data.txt
is the linked file we want to create and `./main/data.txt/ is the path to the existing file:
1New-Item -ItemType SymbolicLink -Name data.txt -Target ./main/data.txt
Which creates a file called data.txt
which is linked to ./main/data.txt
The mklink
version of this is:
1mklink data.txt ./main/data.txt
For more info see [this page](https://superuser.com/questions/1307360/how-do-you-create-a-new-symlink-in-windows-10-using-powershell-not-mklink-exe_
Git Status for Sub-Directories
Check which folders have modified files (only goes one level deep)
1$notGit = "`nNot Git Repositories"2Get-ChildItem -Directory | ForEach-Object {3 Set-Location $($_.Name);4 $status = (git status) 2>&15 if ($status -like "*fatal*") {6 $notGit += "`n-$($_.Name)"7 }8 else {9 Write-Host "$($_.Name)" -ForegroundColor yellow;10 }11 if ($status -like "*nothing to commit*") {12 Write-Host " All Good" -ForegroundColor green;13 }14 if ($status -like "*Changes to be committed*") {15 Write-Host " Uncomitted Files" -ForegroundColor DarkRed;16 }17 if ($status -like "*modified*") {18 Write-Host " Modified Files" -ForegroundColor DarkMagenta;19 }20 if ($status -like "*Untracked*") {21 Write-Host " Untracked Files" -ForegroundColor Red;22 }23 if ($status -like "*pull*") {24 Write-Host " Behind Origin" -ForegroundColor DarkGreen;25 }26 Set-Location ..27}28
29Write-Host $notGit;
Zip and Unzip a File
1Compress-Archive .\DirectoryToZip .\NewFileName.zip2Expand-Archive .\FileToUnzip.zip .\DestinationDirectoryName
Copy and Paste Files
Copy the current directory with:
1Get-ChildItem * | Set-Clipboard
Copy a single file with:
1Get-Item '.\FileToCopy.png' | Set-Clipboard
Paste Item with:
1Get-Clipboard -Format FileDropList | Copy-Item
Send an Email
From this StackOverflow Answer
1Function Send-EMail {2 Param (3 [Parameter(`4 Mandatory=$true)]5 [String]$EmailTo,6 [Parameter(`7 Mandatory=$true)]8 [String]$Subject,9 [Parameter(`10 Mandatory=$true)]11 [String]$Body,12 [Parameter(`13 Mandatory=$true)]14 [String]$EmailFrom="myself@gmail.com", #This gives a default value to the $EmailFrom command15 [Parameter(`16 mandatory=$false)]17 [String]$attachment,18 [Parameter(`19 mandatory=$true)]20 [String]$Password21 )22
23 $SMTPServer = "smtp.gmail.com"24 $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)25 if ($attachment -ne $null) {26 $SMTPattachment = New-Object System.Net.Mail.Attachment($attachment)27 $SMTPMessage.Attachments.Add($SMTPattachment)28 }29 $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)30 $SMTPClient.EnableSsl = $true31 $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($EmailFrom.Split("@")[0], $Password);32 $SMTPClient.Send($SMTPMessage)33 Remove-Variable -Name SMTPClient34 Remove-Variable -Name Password35
36}
Troubleshooting Path Commands
If a command is not running the application/version of the application you’d expect you can try the following steps:
- Refresh your path and try the command again, it may just not be up-to-date. You can use the following function to do that:
1function refresh {2 $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")3}
- If you command is just generally being weird in some way it may be because it is defined/part of another path than the one you expect
To see where a command is being run from, you can try the following:
1Get-Command <command>
e.g. for node:
1Get-Command node
e.g my
node
command was being problematic because it was running the one in my Anaconda path entry (because apparently Anaconda comes with Node)
- In order to ensure that the correct application/command takes precedence move it higher up your path
Create Drive Aliases
On Windows you can alias specific folders as virtual drives (for easy reference or to get around file length restrictions)
To view your aliases/drives you can run:
1> subst2R:\: => C:\repos
To create a new drive you can use:
1> subst X: C:\path\to\folder
Where X
is the drive you would like to map to. Be sure not to have the trailing \
in your folder name
The path to the folder can also be relative:
.\my\rel\path
To remove a drive run the following command:
1> subst R: /D
What Process is Using a Port
To view what process is using a specific port you can run the following command:
1Get-Process -Id (Get-NetTCPConnection -LocalPort 5000).OwningProcess
You can also use the following command:
1netstat -ano | findstr : 8000
Killing Process by ID
If you have the PID, for example using one of the above commands, you can kill us using taskkill
, for example for killing PID 1234
1taskkill /PID 1234 /F
Zipping Files
To zip all the files in a directory you can use the following:
1Compress-Archive -Path ./* -DestinationPath ./output_file.zip
To zip a directory, including the root directory in the Zip use the following:
1Compress-Archive -Path ./dir_to_zip -DestinationPath Compress-Archive -Path ./* -DestinationPath ./output_file.zip
Search for Devices on Network
To view the IP’s of the different devices that are currently connected to your network you can use the following command:
1arp -a
Connect to RDP
To use an RDP file you can make use of the mstsc
command with a path to the RDP file you want to connec with:
1mstsc ./my-cool-server.rdp
Which will then open the RDP file
Switch to Home Directory
You can switch to your home directory on Powershell with cd ~
, the ~
directory represents the user’s home, same as in other OS’s and shells
My Current $PROFILE
Yout Powershell is a script that runs whenever you open a new powershell instance, the functions available in it become part of your session so you can just call them from the terminal. The path to this file is stored in every Powershell instance as the $PROFILE
variable
To open your $PROFILE
in notepad you can run:
1notepad $PROFILE
My current profile which has some common commands is here:
1# POWERSHELL CONFIGURATION FUNCTIONS2# ==================================3# THESE ARE CALLED BY POWERSHELL ITSELF4
5# SETS CUSTOM PROMPT, THIS FUNCTION GETS CALLED ON PS SETUP6function prompt {7 $p = Get-Location8 "$p9!"10}11
12# ENVIRONMENT FUNCTIONS13# =====================14# CONFIGURE ENVIRONMENT15
16# REFRESH SESSION ENVIRONMENT VARIABLES17function _refresh {18 $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")19}20
21# GENERAL UTILITIES22# =================23
24# NAVIGATION25# ^^^^^^^^^^26
27# CD TO MY REPOSITORIES28function _repo {29 Set-Location c:\repos30}31
32# CD TO MY DOCS33function _docs {34 Set-Location C:\repos\PersonalSite\static\content\docs35}36
37# GIT38# ^^^39
40# MERGE GIT "DEVELOP" TO "MASTER"41function _quickmerge {42 git push43 git checkout master44 git merge develop45 git push46 git checkout develop47}48
49# COMMIT ALL SUBMODULE'S FILES AND RUN SAME COMMIT ON PARENT REPO50# FOR THE UPDATED SUBMODULE. RUN FROM SUBMODULE DIRECOTRY51function _updatesub {52 param(53 [string]$commitMessage54 )55
56 $submoduleFolder = Split-Path (Get-Location) -Leaf57
58 git add .59 git commit -m $commitMessage60 git push61 cd ..62 git add $submoduleFolder63 git commit -m $commitMessage64 git push65 cd $submoduleFolder66}67
68# FILE MANIPULATION69# ^^^^^^^^^^^^^^^^^70
71# COPY SOMETHING TO YOUR CLIPBOARD72function _copy {73 param(74 [string]$fileToCopy75 )76
77 Get-Item $fileToCopy | Set-Clipboard78}79
80# PASTE WHAT'S ON YOUR CLIPBOARD81function _paste {82 Get-Clipboard -Format FileDropList | Copy-Item83}84
85# RENAME A FILE86function _rename {87 param(88 [string]$currentFile,89 [string]$newName90 )91
92 Rename-Item -Path $currentFile $newName93}94
95# COPY AND RENAME FILE96function _dupe {97 param(98 [string]$currentFile,99 [string]$newName100 )101 $tempDir = ".temp_nvdupe"102
103 nvcopy $currentFile104 mkdir $tempDir105 cd $tempDir106 nvpaste107 nvrename $currentFile $newName108 nvcopy $newName109 cd ..110 nvpaste111 rm -r $tempDir112}