Introduction
In batch scripts, writing code to do simple things was tedious. PowerShell lets us do things easier where it also excels providing strong support to access and control system resources using the .NET Framework. I cannot but mention some of the code snippets I had written and was of good use.
Background
I was missing the bash prompt of Unix/Linux when I moved to PowerShell. The bash prompt does not show the entire directory path and has a home dir sign. That keeps the terminal clean. Due to security reasons, many restrictions have been applied in PowerShell. For example, you have a script delay.ps1. You cannot run it by entering a delay though execution policy is enabled. I rather decided to use a prefix ss to run all these programs. Now with the provided script, we can enter ss scriptname to run a script simply (works if we even omit the extension or .\).
Using the code
Put the code of the file Microsoft.PowerShell_profile.ps1 in your profile and ss.ps1 where you want to keep your scripts.
You need to have the execution policy enabled on your PC to run PowerShell scripts. To enable this for the current user, you can run PS > set-executionpolicy Unrestricted -scope currentuser.
Inside the scripts
If we want to use Unix like prompt in our Windows PowerShell, we use the following code which includes two functions, prompt
and get-diralias
. The get-diralias
function returns a grave sign in case it meets our set home directory, which is E:\Scripts here.
If it is not a home directory, then we find a backward slash (\). Take only the last part after that slash as a substring. Otherwise if we find that the current location string ends with \, we know that we are in the root of a drive. In that case, we return only the drive and the colon.
$env:homedir=E:\Scripts
# get the last part of path
function get-diralias ([string]$loc) {
# check if we are in our home script dir
# in that case return grave sign
if ($loc.Equals($env:homedir)) {
return "~"
}
# if it ends with \ that means we are in root of drive
# in that case return drive
$lastindex = [int] $loc.lastindexof("\")
if ($loc.EndsWith("\")) {
return $loc.Remove($lastindex, 1)
}
# Otherwise return only the dir name
$lastindex += 1
$loc = $loc.Substring($lastindex)
return $loc
}
# Set prompt
function prompt {
return "[sa@matrix $(get-diralias($(get-location)))]$ "
}
We add another function ss
which provides the following functions:
# To go home
$ ss cd
# To edit powershell profile script
$ ss ep
# To open a text/script file with Powershell ISE
$ ss ise filename.ps1
# List programs which are available in app path that can be run
# with simply putting with ss i.e., ss notepad++ or ss chrome
$ ss list-programs
# run a program from apppath, app path in registry
# is a collection of paths when you run a command
# from run dialog box it looks for executable file paths
# there (correct me if I am wrong)
$ ss chrome
Or
$ ss devenv
ss
is a command that will create the file if the provided file path doesn’t exist. Let’s go into the script. We have the godfather functionss
which manages the commandline arguments in the proper way, gives a warning if no commandline is provided, and calls the ss.ps1 script with those arguments. I did this intentionally to keep the profile file smaller.
function ss() {
if ($args.Count -lt 1) {
return "Please provide correct commandline"
}
elseif ($args.Count -eq 1) {
& "$env:homedir\ss.ps1" $args
}
else {
$cmd = $args[0]
# echo "cmd: `"$cmd`""
$cargs = [string]$args
# echo "cargs: `"$cargs`""
$cargs = $cargs.TrimStart($cmd)
$cargs = $cargs.TrimStart()
# echo "cargs: `"$cargs`""
& "$env:homedir\ss.ps1" $args[0] $cargs
}
return ""
}
ss cd
or ss ep
functionalities are easy to understand. Initially, code for ss ise
was more simple. But ise
seems to behave unstable sometimes. It’s why I corrected the commandline to specify the absolute file path instead of the relative one, i.e., .\filename.ext is relative where e:\folder\filename.ext is the absolute file path.
# ss ise: call powershell_ise editor
if ($cmd.ToLower().Equals("ise")) {
$cargs = [string]$args[1]
$cpath = $cargs
# if the file
if ($cargs.IndexOf("\") -eq "-1") {
$cpath =$(get-location).path+"\$cargs"
}
elseif ($cargs.StartsWith("..\")) {
$cpath =$(get-location).path
$cpath =$cpath.Substring(0, $cpath.LastIndexOf("\"))
$cpath +=$cargs.TrimStart("..")
}
elseif ($cargs.StartsWith(".\")) {
$cpath =$(get-location).path+$cargs.TrimStart(".")
}
if (Test-Path $cpath) {
# echo "1. Path: $cpath"
& $env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell_ise.exe $cpath
}
else {
echo "Creating File $cpath as it does not exist."
echo "# Date: $(get-date)"> $cpath
echo "# Author: $env:USERNAME">> $cpath
& $env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell_ise.exe $cpath
}
break
}
To run programs from the app path, ss
initially looks if the following Registry entry exists: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$(cmdArgument).exe. If it finds it, it takes the default value of that key which is the file path for the executable. We remove the quotation signs from both ends.
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$cmd.exe") {
echo "Starting program $origcmd"
$regitem = Get-ItemProperty
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$cmd.exe"
# Get-ItemProperty
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\notepad++.exe"
$regcmd = $regitem."(default)"
# Modify the command so that arguments don't get splitted
$regcmd = $regcmd.TrimStart("`"")
$regcmd = $regcmd.TrimEnd("`"")
& "$regcmd" $cargs
break
}
elseif (!(Test-Path "$env:homedir\$cmd.ps1")) {
echo "Please check your command"
break
}
Hope these scripts help you automate your works. Thank you.
History
- Initial release - July 11, 2011.