I am not a fan of the big MS. It started a long time ago when my funds were limited and I simply couldn’t afford to keep up with the MS upgrade schedule. Not all of their software back in the day, in my opinion, was all that great. I went cold turkey on as many of the MS products that I could.
There is a lot of open source software that could fill in the empty spots for me and since then most of my work life was on Unix which led to joys of shell scripting (ksh,bash,csh)
I love Unix shell scripting because the shell is basically just the glue to tie together a lot of small command line utilities which makes it easy to create and add extra commands, and Unix has a lot of command line tools. Windows, at that time, had a very weak batch scripting language and a limited number interesting command line commands.
PowerShell
(Eventually) Those folks at MS decided to create their own scripting language called powershell. They decided to take a slightly different route than the Unix crowd. Powershell is an interpreter that contains the logic for doing tasks. This “shell” appears to be more of a replacement for the typical cmd.exe shell that has existed since the beginning (well it used to be command.com) as well as all of the command line programs.
The commands that exist from the powershell are called cmdlets. Unlike Unix these are not a simple executables that can be executed from the cmd shell but are commands that are part of the powershell interpreter. This might give a small bit of extra performance but it also means a new version of powershell is needed to add some new functionality.
The one good thing about the powershell is that it was installed on my computer by default. In addition, The big MS did want to show their security credentials and they have added a security level that must be set before you are able to run any powershell scripts. This security level is essentially determining to which extent you trust powershell scripts with the focus being on either local or from other sources.
This is actually a pretty smart as it is possible to do quite a few things using powershell once you can run the scripts. It would be pretty serious to have such power unlocked by default for any user who happens to execute a powershell script that is an attachment to an email.
However, even accidentally running a powershell script is a bit harder as MS has associated the extension .ps1 to be assigned to notepad. Thus if you click on a script from windows explorer you will simply open up the script in notpad.
In order to run powershell scripts you need to first select an executable permission. There are four different permissions that can be selected in order to set the various rights at different levels.
Level | Description |
---|---|
Restricted | Can not run powershell scripts |
RemoteSigned | Can run local scripts but remote scripts need to be signed. |
Unrestricted | Any script can be run. |
AllSigned | Very secure, requires all scripts to be signed. |
Undefined | Removes existing level |
Changing the level is actually pretty easy but you do need to be an administrator to do so. Simply use the set-executionpolicy cmdlet to set the permission to one of the described levels.
Signed Scripts
I personally am a fan of the unix “permissions” as it is really quite simple and very easy to modify. However, I wouldn’t say that they are the final word in preventing unauthorized scripts from being run.
I guess the final word is trying to protect your scripts is to use Microsoft’s method of creating recognized certificates while using a certification authority infrastructure. If you want you can learn more about this by visiting Microsoft and downloading their best practices document. I didn’t feel up to the task of going through the entire 67 page document so instead I decided to set my execution policy level to RemoteSigned.
This then let me run my fabulous powershell script.
$list = dir echo $list
Actually this small script does quite a bit. It does a directory listing and assigns the output to a variable. Much like the bash shell that variable can be a list and echoed to the output device.
Note: It is possible to run any other programs from this powershell if they are in your path.
Unix friendly
It is possible that the big MS wanted to create a shell that would also appeal to the Unix crowd. I think this is the case as the powershell has the alias command. This gave them the ability to create a bunch of commands that appear to include the common Unix commands.
The alias command links the name to an internal cmdlet which performs some action. One example of this is the “clear” alias being linked to the cmdlet clear-content. The alias’s that they choose appear to look like they were picked to make Unix guys feel comfortable.
PS C:\Windows\system32> alias CommandType Name Definition ----------- ---- ---------- Alias % ForEach-Object Alias ? Where-Object Alias ac Add-Content Alias asnp Add-PSSnapIn Alias cat Get-Content Alias cd Set-Location Alias chdir Set-Location Alias clc Clear-Content Alias clear Clear-Host Alias clhy Clear-History Alias cli Clear-Item Alias clp Clear-ItemProperty Alias cls Clear-Host Alias clv Clear-Variable Alias compare Compare-Object Alias copy Copy-Item Alias cp Copy-Item Alias cpi Copy-Item Alias cpp Copy-ItemProperty Alias cvpa Convert-Path Alias dbp Disable-PSBreakpoint Alias del Remove-Item Alias diff Compare-Object Alias dir Get-ChildItem Alias ebp Enable-PSBreakpoint Alias echo Write-Output Alias epal Export-Alias Alias epcsv Export-Csv Alias epsn Export-PSSession Alias erase Remove-Item Alias etsn Enter-PSSession Alias exsn Exit-PSSession Alias fc Format-Custom Alias fl Format-List Alias foreach ForEach-Object Alias ft Format-Table Alias fw Format-Wide Alias gal Get-Alias Alias gbp Get-PSBreakpoint Alias gc Get-Content Alias gci Get-ChildItem Alias gcm Get-Command Alias gcs Get-PSCallStack Alias gdr Get-PSDrive Alias ghy Get-History Alias gi Get-Item Alias gjb Get-Job Alias gl Get-Location Alias gm Get-Member Alias gmo Get-Module Alias gp Get-ItemProperty Alias gps Get-Process Alias group Group-Object Alias gsn Get-PSSession Alias gsnp Get-PSSnapIn Alias gsv Get-Service Alias gu Get-Unique Alias gv Get-Variable Alias gwmi Get-WmiObject Alias h Get-History Alias history Get-History Alias icm Invoke-Command Alias iex Invoke-Expression Alias ihy Invoke-History Alias ii Invoke-Item Alias ipal Import-Alias Alias ipcsv Import-Csv Alias ipmo Import-Module Alias ipsn Import-PSSession Alias ise powershell_ise.exe Alias iwmi Invoke-WMIMethod Alias kill Stop-Process Alias lp Out-Printer Alias ls Get-ChildItem Alias man help Alias md mkdir Alias measure Measure-Object Alias mi Move-Item Alias mount New-PSDrive Alias move Move-Item Alias mp Move-ItemProperty Alias mv Move-Item Alias nal New-Alias Alias ndr New-PSDrive Alias ni New-Item Alias nmo New-Module Alias nsn New-PSSession Alias nv New-Variable Alias ogv Out-GridView Alias oh Out-Host Alias popd Pop-Location Alias ps Get-Process Alias pushd Push-Location Alias pwd Get-Location Alias r Invoke-History Alias rbp Remove-PSBreakpoint Alias rcjb Receive-Job Alias rd Remove-Item Alias rdr Remove-PSDrive Alias ren Rename-Item Alias ri Remove-Item Alias rjb Remove-Job Alias rm Remove-Item Alias rmdir Remove-Item Alias rmo Remove-Module Alias rni Rename-Item Alias rnp Rename-ItemProperty Alias rp Remove-ItemProperty Alias rsn Remove-PSSession Alias rsnp Remove-PSSnapin Alias rv Remove-Variable Alias rvpa Resolve-Path Alias rwmi Remove-WMIObject Alias sajb Start-Job Alias sal Set-Alias Alias saps Start-Process Alias sasv Start-Service Alias sbp Set-PSBreakpoint Alias sc Set-Content Alias select Select-Object Alias set Set-Variable Alias si Set-Item Alias sl Set-Location Alias sleep Start-Sleep Alias sort Sort-Object Alias sp Set-ItemProperty Alias spjb Stop-Job Alias spps Stop-Process Alias spsv Stop-Service Alias start Start-Process Alias sv Set-Variable Alias swmi Set-WMIInstance Alias tee Tee-Object Alias type Get-Content Alias where Where-Object Alias wjb Wait-Job Alias write Write-Output PS C:\Windows\system32>
This is NOT exactly like Unix. The “ls” alias does do a directory listing but unsurprisingly it does not accept the same options.
Microsofts cmdlets
PowerShell actually implements all the logic in the form of cmdlets. You could find a book that described PowerShell programming along with (hopefully) a big reference section. That is one possible approach but the good news is that PowerShell has built in help.
The cmdlet get-help will return the information about any of the supported cmdlets.
Microsoft also has a very complete webpage that describes the different cmdlets. This information is grouped together by function.
One final note about security
Well, I am glad that I didn’t spend a whole lot of time on setting up an elaborate system to deal with signed certificates. It turns out that there are actually a number of different ways that you can run powershell scripts and some of them get around the existing security settings.
I didn’t actually come up with these methods myself, but instead happened upon the following webpage that elaborated a lot of ways to get around the execution policy.
Of all the methods of bypassing the security I liked the method of piping the script through the interpreter and telling it to ignore the execution permissions by not using anyone’s profile.
Does windows scripting suck? It is a bit too early to answer this question as the only script I have provided is equivalent to the dir command. I will cover a bit more about powershell scripting in part II.