Scripting is always a preferred choice for IT, businesses, server administrators, DBAs and professionals who aim to automate or schedule their routine tasks with flexibility and control. It not only makes you more productive but also improves your daily tasks.
The lack of task automation makes an emerging business lose most of its time and effort on managing its administrative tasks. You may have done tons of things to advertise your business, but when it comes managing your tasks you probably need something that makes your life a lot.
Introduction
Windows PowerShell is one of the powerful command line tools available for scripting. If you are familiar with Unix, DOS or any other command based tools, you would easily get expertise over PowerShell.
Your first script
A simple script in PowerShell can be written in a notepad. it is a sequence of commands called cmdlets
that will be executed one at a time.
- Open notepad
- Type a string: ‘Printing current date time..’
- Type a cmdlet in next line:
get-Date
- Save file: MyFirstScript.ps1
- Right click on the file and click ‘Run with PowerShell’
- You can see the current date time printed on PowerShell Console
Whatever you type in double quotes, is displayed on the console and cmdlets gets executed.
Getting PowerShell on your machine
There is no need of additional installation for the tool, it is a part of Windows 7 and above by default. For earlier versions, it can be downloaded from Microsoft Scripting Center.
Just type windows or powershell in search area after pressing windows logo and you will find two PowerShell menus
Windows PowerShell is for plain console while ISE is Integrated Scripting Environment to write, test and execute scripts in the same window.
Building Blocks
Let us quickly get acquainted with the terminology to start coding. Here are the basic terms used –
Cmdlets
Commands written in PowerShell are named cmdlets
(pronounced as ‘command lets’)which are the foundation of scripting. You can write a series of cmdlets to achieve your tasks. It is written as a verb-noun pair which is easy to remember and self-explanatory.
If we execute following cmdlet, it lists down all the childs from current location –
PS C:\> Get-Childitem
(Get – verb, Childitem – Noun)
Each cmdlet has an associated help file to know about its syntax – Description and parameters required to invoke it correctly. You can use cmdlet ‘Get-Help’ for same.
Aliases
Let us observe the following commands –
The cmdlet Get-childitem
returns the list of files/folders in current directory in this case – C drive.
If you look at other two commands – dir
and ls
, both return the same result. Does that mean there are duplicate commands to solve the same problem?
No, these both are aliases to ‘Get-childitem’. You can create handy aliases of your important commands and use it. This is the reason why your DOS and Unix commands work seamlessly with PowerShell.
Following command sets alias for Set-Location
cmdlet
PS C:\> New-Alias Goto Set-Location
You can find out existing aliases by command type – ‘Alias’ on your machine
PS C:\> Get-Command –Name *
Pipeline
You can use output of one cmdlet in another using pipe character (|). As an example you want to collect some data and then copy the output to a file, you can simply do it with one-line syntax
PS C:\> Get-Childitem | Export-Csv out.csv
Redirection
Two Redirection operators used are > and >>.
These enable you to send particular output types to files and output stream
Code |
Message Type |
* |
All output |
1 |
Success |
2 |
Error |
3 |
Warning |
4 |
Verbose |
5 |
Debug |
Following command writes the out to a file instead of console
PS C:\> Get-Childitem * > out.txt
Operators
Like any other scripting language, PowerShell also provides an exhaustive list of operators to write powerful scripts. Some of the basic operators are listed for your reference here:
Operator |
Symbol |
Definition |
Assignment |
“=,+=,-=,*=,/=,%=,++,–“ |
Assigns one or more values to a variable |
Comparison |
“-eq, -ne” |
Equal, Not equal |
|
“-gt,-ge” |
Greater than, Greater than or equal to |
|
“-lt,-le” |
Less than, Less than or equal to |
|
“-replace” |
Changes specified element in a value |
|
“-match, -notmatch” |
Regular expression matching |
|
“-like, -notlike” |
Matching wildcards |
|
“-contains,-notcontains” |
Returns TRUE if the value on its right is contained in the array on its left |
|
“-in, -notin” |
Returns TRUE only when given value exactly matches at least one of the reference values. |
Logical |
“-and, -or, -xor, -not, !” |
Connect expressions and statements, allowing you to test for multiple conditions |
Bitwise |
“-band” |
Bitwise AND |
|
“-bor” |
Bitwise OR (inclusive) |
|
“-bxor” |
Bitwise OR (exlcusive) |
|
“-bnot” |
Bitwise NOT |
String |
“-Split” |
splits a string |
|
“-join” |
joins multiple strings |
Execution Policy
Powershell executes cmdlets as per set execution policy of the machine or server. Sometimes it becomes necessary to explicitly set the policy on the scripts before executing on different machines.
The Set-ExecutionPolicy
cmdlet is used for the purpose which has four options to choose from –
Policy |
Definition |
Restricted |
No scripts can be run. PowerShell can be used only in interactive mode |
AllSigned |
Only scripts signed by a trusted publisher can be run |
RemoteSigned |
Downloaded scripts must be signed by a trusted publisher before they can be run |
Unrestricted |
No restrictions – all scripts can be run |
Useful Commands
There are more than two hundred in-built cmdlets for use and developers can built complex ones by using the core commands. Some of the useful commands are listed below:
Cmdlet |
Syntax |
Output |
Usage |
Get-Date |
Get-Date |
Sunday, March 26, 2017 6:12:40 PM |
Gets current date and time |
(Get-Date).AddMinutes |
(Get-Date).AddMinutes(60) |
Sunday, March 26, 2017 7:12:40 PM |
Adds 1 hour to current date and time |
Copy-Item |
Copy-Item c:\source.txt d:\destination |
Copy source.txt to destination folder |
Copying files and folders |
Clear-Eventlog |
Clear-Eventlog -LogName |
Clears all enteries from specified event log |
|
Restart-Service |
Restart-Service -Servicename |
Restarts service |
|
Get-ChildItem |
Get-ChildItem |
Gets all files and folders |
Some parameters make his more useful –
force – to run without user confirmation on special folders
include – to include certain files or folders
exclude – to exclude certain files
path – specified path instead of current directory |
Set-Content |
Set-Content C:\textFile.txt “Text being added here from PowerShell” |
Saves text to a file |
|
Remove-Item |
Remove-Item C:\test -Recurse |
Removes all contents from a folder |
User will not be prompted before deletion |
(Get-WmiObject -Class Win32_OperatingSystem -ComputerName .).Win32Shutdown(2) |
(Get-WmiObject -Class Win32_OperatingSystem -ComputerName .).Win32Shutdown(2) |
Restart current computer |
|
Real-world Scenario
Let’s see how PowerShell made the life of a server administrator easy!
John Bell, one of the system administrator of an MNC is catering to some 2000 users and update patches on their desktops remotely through Windows Server 2010 and MS System Center Configuration Manager, SCCM. Now, when one or more patches get scheduled to run during night hours, often they failed on couple of machines due to disk space scarcity and lots of manual intervention and rework is required to close the current job. One of his colleagues suggested to take a proactive approach and get a list of machines with details of what is being stored on C drive, a day before patch execution job, so John decided to create a powershell script to get executed through SCCM on client machines automatically and send give a detailed report in a csv file to review the data usage and bottle necks.
Here is what he wrote (added inline comments for clarity) –
01 |
## Initiate source and destination |
03 |
$outFile="D:\output.csv" |
04 |
## Get last logged in username |
05 |
$strName=$env:username |
08 |
$compName=$env:computername |
09 |
## get total size and free space of c drive of selected computer |
10 |
$disk=Get-WmiObjectWin32_LogicalDisk-ComputerName$compName-Filter"DeviceID='C:'"| |
11 |
Select-ObjectSize,FreeSpace |
12 |
$TotalSpace= ($disk.Size/1gb) |
13 |
$FreeSpace= ($disk.FreeSpace/1gb) |
14 |
## initiating two arrays for getting a list |
18 |
## Include Hidden Files |
19 |
$arr=Get-ChildItem$filePath-Force|where {$_.PSIsContainer -eq$False} |Select-ObjectName,FullName,CreationTimeUtc,LastWriteTimeUtc,length |
20 |
"Gathering information of files completed. Folder scan started..." |
21 |
## Include Hidden Folder |
22 |
$arr=Get-ChildItem$filePath-Force|where {$_.PSIsContainer -eq$True} |Select-ObjectName,FullName,CreationTimeUtc,LastWriteTimeUtc |
30 |
## Include Hidden Files |
31 |
$FSize= (Get-ChildItem$item.FullName -Force-recurse-ErrorActionSilentlyContinue|Measure-Object-propertylength-sum).Sum |
32 |
$FSize=[math]::round($FSize/1gb,2) |
33 |
$PerHDD=[math]::Round($FSize/$TotalSpace*100,2) |
36 |
$PLogs {break} ;$MSOCache {break} ; $Recovery {break} ; $SystemVolumeInformation {break} |
37 |
default {$own=Get-Acl$item.FullName} |
39 |
$object=New-Object-TypeNamePSObject |
40 |
$object|Add-Member-Name'CompName'-MemberTypeNoteproperty-Value$compName |
41 |
$object|Add-Member-Name'TotalSpace'-MemberTypeNoteproperty-Value$TotalSpace |
42 |
$object|Add-Member-Name'FreeSpace'-MemberTypeNoteproperty-Value$FreeSpace |
43 |
$object|Add-Member-Name'Name'-MemberTypeNoteproperty-Value$item.Name |
44 |
$object|Add-Member-Name'FilePath'-MemberTypeNoteproperty-Value$item.FullName |
45 |
$object|Add-Member-Name'Type'-MemberTypeNoteproperty-Value$FType |
46 |
$object|Add-Member-Name'Size'-MemberTypeNoteproperty-Value$FSize |
47 |
$object|Add-Member-Name'In'-MemberTypeNoteproperty-Value'GB' |
48 |
$object|Add-Member-Name'% of HDD'-MemberTypeNoteproperty-Value$PerHDD |
51 |
"Folder scan completed." |
52 |
$finalObj|Export-Csv$outFile |
53 |
"Job Completed! File created successfully" |
Output is a csv file –
CompName |
TotalSpace |
FreeSpace |
Name |
Size |
In |
% of HDD |
<compName> |
99.99999619 |
29.15378189 |
Program Files |
2.12 |
GB |
2.12 |
Conclusion
PowerShell is extremely powerful and handy when comes to manage server and database tasks and can quickly automate tasks for you. Give it a try! Happy Coding!