Windows PowerShell For .NET Developers - Second Edition - Sample Chapter
Windows PowerShell For .NET Developers - Second Edition - Sample Chapter
Second Edition
P U B L I S H I N G
Chendrayan Venkatesan
Sherif Talaat
Second Edition
ee
Sa
pl
e
P r o f e s s i o n a l
E x p e r t i s e
D i s t i l l e d
Chendrayan Venkatesan
Sherif Talaat
P U B L I S H I N G
has worked for the Information, Computer and Technology industry since 2005.
Chen V started his career as Windows XP technical support engineer and became
a SharePoint IT Pro in the year 2007. He mainly focuses on automating Microsoft
Technologies such as SharePoint, LYNC, and Exchange. He was awarded the
Microsoft Most Valuable Professional (MVP) in 2014. He speaks on Windows
PowerShell, SharePoint Servers, Content Management, and IT Process Automations.
He blogs in http://chen.about-powershell.com and is mentoring three IT
professionals in PowerShell. He is a TechNet Wiki addict and has introduced
Windows PowerShell as a category in the TechNet Wiki Guru award competition.
To connect with Chen V you can visit his web site http://about-powershell.com
or choose your favourite social media twitter @ChendrayanV or LinkedIn
nl.linkedin.com/in/chendrayanv.
Preface
Windows PowerShell is no longer a secret in the world of IT. Starting in 2006,
it's been growing and has now turned out to be a massive automation platform
especially for Microsoft products and technologies.
Windows PowerShell 5.0 for .NET Developers is your self-start guide to performing
automation using Windows PowerShell. This book will help you to understand the
PowerShell syntax and grammar and will also teach you techniques to remove the
rough edges of manual deployments. Packed with PowerShell scripts and sample C#
codes to automate tasks, it also includes real-world scenarios, such as administrating
office servers to help you save time and perform deployments swiftly and efficiently.
Preface
Chapter 5, Exploring Application Programming Interface, covers the key benefits of the
API and using it in Windows PowerShell, Exchange Web Services, LYNC Client-side
API, and SharePoint Client Side Object Model; you'll walk through a demo to create
a PowerShell module in C# for office servers.
The IT industry is growing rapidly; to adapt and minimize the impact, we need to
plan and design our infrastructure so as to meet the growing needs with minimum
chaos. It's challenging and really difficult to automate the tasks without PowerShell.
Windows PowerShell plays a major role by not only enabling task automation,
but also allowing us to design our infrastructure with the help of IT professionals
and developers.
Developers from the .NET background can quickly understand PowerShell.
Developers can easily create their own cmdlets (cmdlets, pronounced as command
lets, are nothing but the lightweight commands used in Windows PowerShell) and
leverage it in the infrastructure as needed. Thus, the deployment tasks become easier
and the productivity increases by automation.
Come, let's dive into Windows PowerShell 5.0 and its features.
Before we begin, let's note that Windows PowerShell 5.0 is not a stable
release. So, if you identify any bugs in the command, you can file a case
at http://connect.microsoft.com.
PowerShell scripting
[2]
Chapter 1
You may wonder, why Windows PowerShell? Why not VBScript? This is a very
common question that most administrators think. It's good to know both, but
VBScript is fading, and compared to PowerShell, it is very limited. Windows
PowerShell can access all .NET libraries, which helps us explore DLLs easily; on the
other hand, VBScript has limitations. If you are a beginner Windows PowerShell
will be a better choice because it is easier to understand and very powerful. The
Windows PowerShell cmdlets are rich and very easy to understand. Using Windows
PowerShell, we can avoid repeated steps, automate administration tasks, avoid GUI
clicks, and do much more. This is not limited to IT Professionals; developers can also
do much more by exploring Windows PowerShell, such as performing development
tasks faster than before.
From Windows PowerShell 5.0 onward, we can develop classes, parse structured
objects using the new cmdlets, and do the package management easily using the
PackageManagement module. This module is introduced in version 5.0 but was
formerly known as the OneGet module; many such modules are enhanced in
the new version.
[3]
But wait, this is not all; you can refer to the following link to get a list of
the new features in Windows PowerShell 5.0:
https://technet.microsoft.com/en-us/library/hh857339.
aspx#BKMK_new50
[4]
Chapter 1
It's best practice to know your PowerShell version before you start doing an exercise
or start using scripts from the Internet.
To check the current version of PowerShell, you can simply run the following code:
$PSVersionTable
[5]
Windows Server 2012 R2 has WMF Version 4.0 by default. Let's upgrade it to WMF
5.0. If you are performing this task on Windows 7 or Windows 2008 R2 with SP1,
install WMF 4.0 prior to WMF 5.0.
Following are the links where you can download the .NET framework and
WMF from:
WMF 5.0http://www.microsoft.com/en-us/download/details.
aspx?id=46889
Do read the system requirements before proceeding
into the production environment. The installation of
WMF 5.0 requires a reboot.
Once the .NET framework 4.0 is in place, update it to the .NET framework 4.5.
As per the Microsoft Document, the .NET framework 4.5 is included in Windows 8
and Windows Server 2012. We can skip the .NET framework 4.5 installation.
We need to identify and install the correct package of WMF 5.0. For Windows
Server 2012, we need to download the 64-bit version of it, which is WindowsBlueKB3055381-x64.msu.
Open the MSU package and you will see the prompt, as shown in the following
screenshot:
[6]
Chapter 1
1. Click on Yes.
2. Read and accept the license agreement, as shown in the following screenshot:
[7]
4. Click on Restart Now when you see the following window on your screen:
[8]
Chapter 1
Ignore x86 in the Windows PowerShell ISE (x86) for now. This is a 32-bit
ISE, and throughout this book, we will focus only on the 64bit ISE.
The location of the Windows PowerShell console host and ISE is:
C:\Windows\System32\WindowsPowerShell\v1.0
The file name powershell.exe is the console host and powershell_
ise.exe is the Integrated Scripting Environment.
[9]
By default, the background color is blue, and in the foreground, the color of the text
is white.
There is no need to type out the complete command; the PowerShell console allows
Tab Completion. For example, Get-Se + Tab completes the Get-Service command.
Tab completion is not only for the commands and parameters; we can also select the
properties using tab key.
To execute the following PowerShell code:
Get-Service -Name BITS | Select -Property Name , Status
[ 10 ]
Chapter 1
There are multiple ways to start a PowerShell console: we could either use the Run
dialog box, or type PowerShell in an open command-line window. These techniques
allow you to pass arguments to Windows PowerShell, including the switches that
control how Windows PowerShell works and the parameters that execute additional
commands. For example, you can start Windows PowerShell in the no-logo mode
(which means that the logo banner is turned off) using the startup command,
PowerShell -nologo. By default, when you start Windows PowerShell via the
command shell, Windows PowerShell runs and then exits. If you want Windows
PowerShell to execute a command and not terminate, type PowerShell /noexit,
followed by the command text.
We can use this to schedule our script in task schedulers. To see all the switches, run
the following command:
PowerShell.exe /?
Options: Using the Options tab, we can see Cursor Size, Command History,
and Edit Options, and adjust them as we require.
While setting the cursor size, we have three options: Small, Medium, and
Large. Here, small is 25 pixels, medium is 50 pixels, and large is 100 pixels.
[ 11 ]
[ 12 ]
Chapter 1
Font: Using the Font tab, we can change the size, style, and type. Before
applying changes, we can preview the console host using the preview window.
The following image illustrates the Font tab:
[ 13 ]
Layout: Using the Layout tab, we can set the screen buffer size, window size,
and window position. Similarly to the Font tab, this also has preview window.
The following image illustrates the Layout tab:
[ 14 ]
Chapter 1
Colors: Using the Colors tab, we can set the screen text, screen background,
pop up text, and popup background values. The current RGB values are
shown in the Selected Color Values section. The modifications can be
previewed before applying.
The following image illustrates the Colors tab:
[ 15 ]
Press F7 to see the history; this pops up a tiny window as shown in the
following image:
[ 16 ]
Chapter 1
Administrator: Windows PowerShell is the default title. Now let's change this to
Windows PowerShell 5.0 April 2015 Preview. Run the following commands:
(Get-Host).UI.RawUI
(Get-Host).UI.RawUI | GM
The preceding code returns the current settings and its members.
[ 17 ]
WindowTitle is a property for which we can get and set a value and whose datatype
is String. We will discuss this in detail in the Understanding Objects section. Now,
let's execute the following code to change the title of the console host:
[ 18 ]
Chapter 1
Using GUI, we can set the cursor size to small, medium, or large, which allows only
25, 50, or 100 respectively. But, PowerShell allows us to customize more by executing
the following command:
(Get-Host).UI.RawUI.CursorSize
The previous command returns the current cursor size. Run the following command:
(Get-Host).UI.RawUI.CursorSize.GetType()
[ 19 ]
Now, let's change the cursor size to 72 by executing the following command:
(Get-Host).UI.RawUI.CursorSize = 72
[ 20 ]
Chapter 1
[ 21 ]
1: Script pane
2: Command pane
3: Commands add-on
The script pane's visibility can be adjusted using the keyboard shortcuts, Ctrl + 1,
Ctrl + 2, Ctrl + 3, which sets the script pane to top, right, and maximized, respectively.
This makes it easy for us to view the command and result that we need.
The command pane will be hidden if we maximize the script pane.
[ 22 ]
Chapter 1
[ 24 ]
Chapter 1
The points marked in the figure are explained in the following list:
3: Click on Settings.
4: Select the sections you need to know. For example, unselect Examples to
hide the example section in the help window.
Benefits of an ISE
In comparison with the PowerShell console host, an ISE has a lot of benefits, and I
will list a few of them here:
[ 25 ]
You can search for the script you need. Type the script's name in the textbox
provided, right-click on the script, and select either Add to favorites or the
Download option.
[ 26 ]
Chapter 1
The scripts that you download will appear in the Downloads tab.
You can set the language, download locations and network settings by
clicking on the settings icon in the upper-right corner.
[ 27 ]
[ 28 ]
Chapter 1
The command shown before was just an example. With reference to this, we can
build code as per our needs using .NET classes.
Getting help
Functions: These are a block of code that are very helpful for script organization
The internal commands of Windows PowerShell are called cmdlets. Cmdlets are
always named in the verb-and-noun combination. This appears as Verb-Noun, for
example Get-Service and Stop-Service, where Get and Stop are verbs, and
Service is a noun.
(Verb)Action
(Noun)Something to be acted on
For example, Get-Service
Let's execute the following command:
Get-Command
[ 29 ]
The previous command will list all the installed commands from the computer and
retrieve only the cmdlets, functions, and aliases.
To retrieve only cmdlets, we can use the CommandType parameter, as shown in the
following command:
Get-Command -CommandType Cmdlet
[ 30 ]
Chapter 1
Now, let's explore the commands. In the following example, we will take a look
at the cmdlet Get-Service. Since we know the cmdlet up front, let's collect more
information such as the cmdlet version and source, as follows:
Get-Command Get-Service
The points marked in the figure are explained in the following list:
To retrieve the commands for a specific module, we need to use the Module
parameter, which accepts the module name (Source) as we saw in bullet 4.
The following is an example of the command:
Get-Command -Module Microsoft.PowerShell.Management
[ 31 ]
Let's see the alternate of the Get-Service cmdlet using the .NET class. To do
this, let's find the TypeName of the Get-Service cmdlet by executing GetService | Get-Member and this gives the TypeName as System.ServiceProcess.
ServiceController. Windows PowerShell allows us to use this directly as follows:
[System.ServiceProcess.ServiceController]::GetServices()
Now, let's take a look at how the command that we just discussed works.
Here, we will consume the .NET ServiceController class in PowerShell and
invoke the GetServices() method.
The GetServices method has an overload with a machineName parameter. To find
this, we will execute the following command:
[System.ServiceProcess.ServiceController]::GetServices
The difference is that here, we did not use parentheses. The output of
OverloadDefinitions is as follows:
OverloadDefinitions
------------------static System.ServiceProcess.ServiceController[] GetServices()
We can query the service information of a remote computer by passing the host
name of the remote computer as the machineName parameter, as follows:
[System.ServiceProcess.ServiceController]::GetServices('RemoteServer')
Getting help
This is the most important and interesting topic. No matter what technology we
consume, all we need to know is the way to get help for it. Most IT professionals
and developers say that they use Google to find this.
[ 32 ]
Chapter 1
For PowerShell, help is much more focused. It's very difficult to remember all the
commands. So, we can search for a command and find help for the same. Let's take
a look at how to seek help for Windows PowerShell cmdlets.
Get-Help Get-Service
SYNTAX: This gives us the syntax of the commands, which includes all its
parameters and its type
RELATED LINKS: This contains the URL of online versions of the command,
and other commands related to the one we are looking for help regarding
[ 33 ]
If more information than that fitting the page view is to be displayed, the console is
paginated. For example, if we execute the Get-Help Get-Service -Detailed |
more command, the details will output as shown in the following image:
If we press Enter, we can view one line after another, whereas pressing the space key
will give a page view.
Keep your files updated using the Update-Help cmdlet as shown in the
following command. Ensure that your machine has internet connectivity
and execute the following command:
Update-Help Verbose
This cmdlet is designed to download and install help files on our computer.
The output is illustrated in the following image:
[ 34 ]
Chapter 1
Ensure that you have an Internet connection while updating your help. The reason
for updating help is to keep the help document up-to-date. Let us learn more about
the Get-Help cmdlet:
The Help cmdlet is an alias for Get-Help (Aliases will be covered in the
next section).
The Get-Help cmdlet allows us to view the online help using the Online
parameter. The following command will open the online URL in the default
web browser:
Get-Help Get-Service Online
The Get-Help cmdlet allows us to view the help content in a separate user
interface. The following is the command that needs to be executed:
Get-Help Get-Service ShowWindow
[ 35 ]
Understanding aliases
Using aliases in Windows PowerShell is not advised by many. The reason for this is
readability and understandability. Developers are comfortable using an alias because
it's easier, but the difficulty is in remembering the alias for each cmdlet.
The bottom line is that aliases are shortcuts for Windows PowerShell cmdlets.
Windows PowerShell has two types of aliases:
The built-in alias: This is an alias that represents PowerShell's native cmdlets
The following command retrieves all the commands available in the Microsoft.
PowerShell.Management module:
Get-Command -Module Microsoft.PowerShell.Management
Using the following alias, we can achieve the same output as with like:
gcm -Module Microsoft.PowerShell.Management
Chapter 1
Let's explore all the commands related to an alias. The module name for aliases'
commands is Microsoft.PowerShell.Utility:
Get-Command -Name '*Alias*'
For now, ignore the PoshBoard module; we will discuss modules in Chapter 2,
Unleashing Development Skills Using Windows PowerShell 5.0.
To find an alias of any given command, we can simply execute the following code:
Get-Alias -Definition Get-Alias
CommandType
Version
Name
Source
-----------------
---------
Alias
Here, gal is an alias of the Get-Alias cmdlet. The Get-Alias cmdlet will retrieve all
the available aliases in your local computer.
PowerShell allows us to create aliases for any given valid cmdlet. To create a new
alias, we execute the following command:
New-Alias -Name W -Value Get-WmiObject -Description "Learning
PowerShell" -Verbose
Now, let's take a look at how the command we just discussed works.
[ 37 ]
[ 38 ]
Chapter 1
Using the Set-Alias command, we can do the same, but it allows us to change
the association later. In the preceding example, we created an alias named W for
the Get-WmiObject command. If we try to create an alias with the same name
for another command, the following error appears:
In this scenario, we can use the Set-Alias command to change the alias' association.
Run the following code:
PS C:\> Set-Alias -Name W -Value Get-Service -Description 'Change
Association' -Verbose
VERBOSE: Performing the operation "Set Alias" on target "Name: W Value:
Get-Service"
If you create more aliases in your machine, you can move them to other machines
using the following two cmdlets:
In this exercise, we will create an alias for the Test-Connection cmdlet and use it in
other machines. The Test part will be the alias of Test-Connection. Following is the
command to set the alias' name:
New-Alias -Name Test -Value Test-Connection -Description "Testing"
-Verbose
[ 39 ]
Let's use the Export-Alias cmdlet and export only this alias using the
following command:
Export-Alias -Name test C:\Temp\CustomAlias.txt Verbose
Move this text file to another computer and use the Import-Alias cmdlet to do this.
Look at the following image:
The steps marked in the image we just discussed are explained as follows:
1: Here, I used the Import-Alias cmdlet and have given the path where I
copied the text file
2: Here, I used the Get-Alias cmdlet to verify the existence of the alias
Chapter 1
So, you can simply use Remove-Item to delete the alias. Execute the
command as shown in the following image:
Understanding expressions
Windows PowerShell supports regular expressions. We know that PowerShell is
built using the .NET framework. So, it strongly supports the regular expressions
in .NET.
Developers prefer to use regular expressions to solve complex tasks such as
formatting display names, manipulating files, and so on.
Regex can either be used by comparing operators or implementing the .NET class.
The MSDN reference link for the regex class is https://
msdn.microsoft.com/en-us/library/system.text.
regularexpressions.regex%28v=vs.110%29.aspx.
[ 41 ]
Before we proceed with regular expressions, let's explore a few things about operators.
To know about operators, we can run the following code:
help about_Operators -ShowWindow
[ 42 ]
Chapter 1
To retrieve help for all the operators in Windows PowerShell, you can run each of
the following lines of code and explore their usage:
help about_Arithmetic_Operators
help about_Assignment_Operators
help about_Comparison_Operators
help about_Logical_Operators
help about_Type_Operators
help about_Split
help about_Join
help about_Redirection
Here is a command that uses a regular expression to check whether the first three
characters are digits in a given string.
[ 43 ]
For example, the given string is 123-456-ABC. Then, the command would be
as follows:
"123-245-ABC" -match '^\d{3}'
{3}: This matches the previous elements n times. In our case, it's three times.
Use the following regular expression to remove the white space characters from any
given string:
"Power Shell" -replace '\s' , ''
The given input string is Power Shell. The expression removes the white space
between Power and Shell in the string and outputs the Powershell word. The
white space is removed as explained in the following steps:
[ 44 ]
Chapter 1
The commands that we just discussed return the output as LastName, FirstName.
Consider the given string as FirstName12345 LastName:
#Given Name: FirstName12345 LastName
#Required Output: LastName, FirstName
'FirstName12345 LastName' -replace "\d+" -replace "([a-z]+)\s([a-z]+)"
,'$2, $1'
The commands that we just discussed return the output as LastName, FirstName.
The output of the previous two expressions is illustrated in the following image:
Similarly, PowerShell allows us to use the regex class to perform the same tasks.
Execute the following code:
[Regex]::IsMatch('PowerShell' , 'PowerShell')
The MSDN TechNet article for the regex class is at the following link:
https://msdn.microsoft.com/en-us/library/system.
text.regularexpressions.regex%28VS.80%29.aspx
[ 45 ]
The IsMatch method is a member of the regex class. This method is overloaded,
which indicates whether the regular expression finds a match in the input string.
This is a simple example to check whether a string contains another string.
The MSDN TechNet article for the regex class members is at the
following link:
https://msdn.microsoft.com/en-US/library/system.text.
regularexpressions.regex_members%28v=vs.80%29.aspx
The output of the code that we just discussed is illustrated in the following image:
To remove the numbers from the given string using regex, we execute the
following command:
[Regex]::Replace('12String' , '\d{2}' , '')
[ 46 ]
Chapter 1
The command that we just considered returns the output as String. We get this
output as explained in the following steps:
The '\d' shorthand character represents the digits and {n} checks n times.
In our case, it's two times.
Understanding objects
In general, a term object is something that we can touch and feel, and the same
is applicable for PowerShell as well. An object in PowerShell is a combination
of methods and properties:
Objects = Properties + Methods
A property is something that we can get or set. In short, properties store information
about the object.
A method is an action to be invoked on a particular object.
Objects are constructed using their types, properties, and methods.
In this section, we will cover the following topics:
Before we explore objects, let's have a look at the help documentation using the
following commands:
help about_Objects
help about_Properties
help about_Methods
The objects that we see in PowerShell are a part of the .NET framework, and
PowerShell will allow us to create custom objects as well.
From Windows PowerShell 5.0 onward, we can create objects
using a class. This will be covered in the Chapter 2, Unleashing
Development Skills Using Windows PowerShell 5.0.
[ 47 ]
Now, let's explore objects in detail. In the following example, we will use the Get-
Date command:
$Date = Get-Date
The Get-Member cmdlet is our friend, and helps us to explore the members and
properties. To take a look at the available properties and methods, we can run the
following code:
Get-Date | Get-Member -MemberType All -Force
[ 48 ]
Chapter 1
The definitions of the property is shown as {get;}. Let's explore the property now,
as follows:
(Get-Date).DateTime
The command that we just considered displays the current date and time of the
local machine.
Now, let's take a look at how the command that we just discussed works, in the
following list:
The DateTime property shows the current system's date and time.
We will get current date and time as output. For example, Tuesday, June 02, 2015
12:15:51 PM.
[ 49 ]
To invoke the methods of an object, we will follow the same procedure. But,
if the method needs arguments, we need to pass it accordingly, as shown in
the following command:
Get-Date | Get-Member -MemberType Method Force
Here, we added one day to the current day and the output is as follows:
Wednesday, June 03, 2015 12:55:35 PM
The output of the command we just discussed retrieves all the members of $PSISE.
One of the property options that hold all the options of the ISE is as follows:
$psISE.Options
To change the script pane's background color, we execute the following code:
$psISE.Options.ScriptPaneBackgroundColor = 'Green'
[ 50 ]
Chapter 1
Understanding pipelines
A Windows PowerShell pipeline is used to join two or more statements with a
pipeline operator. The Pipeline operator is '|'.
We have used pipelines in previous examples; let's know about pipeline use
case scenario.
In this section, we will cover the following:
Here, Command1 sends the object to Command2; the processed object will then be sent
to Command3, which will output the results. Take a look at the following command:
help about_Pipelines -ShowWindow
The parameter must accept input from a pipeline (however, not all do so)
The parameter must accept the type of object being sent or a type that the
object that can be converted to
Name
DisplayName
------
----
-----------
Running
BITS
The Get-Service cmdlet gets the object representing the BITS service.
Using the Stop-Service cmdlet, we can stop the service. The -Verbose parameter is
to show the operation handled, as shown in the following code:
Get-Service -Name BITS | Stop-Service -Verbose
[ 51 ]
The output of the command we just discussed is illustrated in the following image:
Using pipeline, we can do many more tasks, such as sorting, grouping, looping, and
so on.
How do we find the parameter that accepts pipeline? Using help and pipeline, we
can do this as shown in the following code:
help Get-Service -Parameter * | Select name , PipelineInput
The output of the command we just discussed is illustrated in the following image:
[ 52 ]
Chapter 1
In short, the pipeline passes the output to another command so that the next
command has something to work with or simply connects the output to other
commands. This helps IT professionals automate tasks such as inventorying,
reporting, and so on.
2: This is the pipeline operator used to pass the output to the next command
3: The Export-csv cmdlet is used to save the output in the CSV format
[ 53 ]
I prefer to export data in the XML format using the Export-Clixml cmdlet because it
holds a lot more information. Take a look at the following command:
Get-Process | Export-Clixml C:\Temp\Process.xml
[ 54 ]
Chapter 1
The output of the command we just discussed is shown in the following image:
Using pipelines, we can connect multiple commands and get effective solutions, as
explained in the following list:
[ 55 ]
Basics of filtering
Basics of formatting
Using the Select-Object cmdlet, we can select the first and last n items from the
collection of objects. The Select-Object cmdlet can be used to retrieve only unique
values (ignoring duplicates).
[ 56 ]
Chapter 1
Now, let's explore Select-Object for filtering. Let's consider that we have a set of
objects from 65 to 90; to select the first 10, we need to pipe and use Select-Object,
as shown in the following command:
65..90 | Select -First 10
The Where-Object cmdlet is used to filter data returned by the other cmdlet. This
cmdlet accepts comparison operators.
Let's explore the syntax of the Where-Object cmdlet, as follows:
(help Where-Object).Syntax
[ 57 ]
The output of the command we just considered is illustrated in the following image:
Consider an array from 1 to 5. To select values greater than 3, we use the WhereObject alias, ?, next to the pipeline operator, as shown in the following command:
1..5 | ? {$_ -gt 3}
From Windows PowerShell 4.0 onward, we can avoid pipelines for the ForEach and
Where objects, as follows:
(65..90).ForEach({[char][int]$_})
[ 58 ]
Chapter 1
The output of the code we just discussed is shown in the following image:
Now, let's take a look at how this works in the following list:
The (65..90) range uses the range operator, ..; these are the ASCII values
of A-Z
[ 59 ]
Now, let's take a look at how this works in the following list:
The (1..10) range uses the range operator, ..; this is the 1 to 10 array
of the object
The Where method accepts the expression, mode, and number to return
We can use the Where statement with different modes. In the following example, we
will select the first three values, where the number is greater than or equal to 5. Now,
let's consider the following code:
(1..10).Where({$_ -ge 5}, 'First' , 3)
[ 60 ]
Chapter 1
Now, let's take a look at how this works in the following list:
The (1..10) uses the range operator, .., and this is the 1 to 10 array
of the objects
In this expression, {$_ -ge 5} is an object greater than 5, First is the mode,
and 3 is the value for the number to be returned.
Similarly, we can use the Split mode as well. Using this, we can split the given
collection of objects, as shown in the following code:
$section1 , $section2 = (1..100).Where({$_ -le 50} , 'Split' , 0)
$section1
$section2
The $section1 variable contains values from 1 to 50, and the $section2 variable
contains values from 51 to 100.
Avoid pipelines as much as you can. Use appropriately, because in
larger script we may end up having a performance issue.
Use Measure-Command and analyze the performance of commands
using pipelines.
Here is a table comparing commands using pipeline with those that don't use
a pipeline:
With pipeline
Result in
milliseconds
Without pipeline
Result in
milliseconds
65..90 |
%{[char]
[int]$_}
1..10 | ?
{$_ -ge 5} |
Select -First
3
(65..90).ForEach({[char]
[int]$_})
42
PowerShell formatting
Windows PowerShell has a set of cmdlets that allows us to format the output. To find
the cmdlets to format, use Verb Format to search, as shown in the following code:
Get-Command -Verb Format
[ 61 ]
Let's take a look at the default formatting of Windows PowerShell by executing the
following the cmdlet:
Get-Process | Select First 5
The headers are not exactly property names. This formatting is done using the file
name, DOTNETTYPES.FORMAT.PS1XML.
The location of the file is $PSHome. Take a look at the following image:
[ 62 ]
Chapter 1
The following list explains the points marked in the preceding image:
The first thing we see in the XML file is the following warning:
Do not edit or change the contents of this file directly. Please see
the Windows PowerShell documentation or type.
So, let's not make any kind of modifications. Instead, let's take a look at the cmdlets
to make minor modifications as desired, as shown in the following image:
In the following example, we will use the Where method to select n items required to
keep the output precise and short.
The help command to format the table is as follows:
help Format-Table -ShowWindow
Let's select the first five running services and format them as follows:
(Get-Service).Where({$_.Status -eq 'Running'},'First',5) | Format-Table
[ 63 ]
The output of the command we just discussed is shown in the following image:
The following image shows all three alignments: left, right, and center:
Chapter 1
The following is the command to custom format using the Format-Custom cmdlet:
Get-Service | Format-Custom
Use the Get-FormatData cmdlet to view the formatting data from the Format.
ps1xml formatting files. In this demo, we will try to customize the default format in
the current session, as follows:
1. Identify the type name of the command. For example, here, we will use the
Get-Process | GM command.
[ 65 ]
3. Now, append the text of the column header in the PS1XML file in the Temp
folder, as shown in the following command:
Update-FormatData -PrependPath C:\Temp\TestView.Format.PS1XMl
[ 66 ]
Chapter 1
We need not be limited to only the available snippets; we can create our own
snippets. In this demo, we will try to create a snippet. This is a simple snippet
to add a mandatory parameter, which we can reuse in any of our functions.
This helps developers and IT professionals do the scripting faster.
There is no need for more typing; we just need to add a snippet wherever we need
reusable codes, as shown in the following code:
$m = @'
Param(
[Parameter(Mandatory=$true)]
[String]
$String
)
'@
New-IseSnippet -Text $m -Title Mandatory -Description 'Adds a Mandatory
function parameter' -Author "Chen V" -Force
[ 67 ]
We used a few parameters with Text , which is the skeleton code; Title,
which can be any friendly name; Description, which describes the snippet
in short; and Author, which is the author's name
After the code is executed, it creates a PS1XML file in the location, $home\
Documents\WindowsPowerShell\Snippets\
The file name will be your titlein this case it's Mandatory.Snippets.PS1XML
We can copy and place it any machinepressing Ctrl + J will
show Mandatory in the snippets.
The following image illustrates the output of the newly created snippet:
The following are the steps that explain the points marked in the preceding image:
[ 68 ]
Chapter 1
Using variables
[ 69 ]
This script prompts for user input; once the value is entered, it stores it in the $value
variable, as shown in the following image:
[ 70 ]
Chapter 1
Using the New-Variable cmdlet, a variable can be created along with a scope
definition. In the following example, let's create a variable name, ws, which
holds the value of the Windows service, and sets the scope to Global:
New-Variable -Name 'ws' -Value (Get-Service) -Scope Global
Let's write a simple script that prints hello world on the screen:
#Windows PowerShell Script to Retrieve Windows Services
Write-Host "Hello, World!" -ForegroundColor Green
To run the PowerShell script, you need to call the script using a dot (.) operator
followed by backward (\) slash.
The extension of the PowerShell script file should be .PS1.
[ 71 ]
env:\username).Value
"$Filepath\style.CSS"
font-family:Calibri;
font-size:10pt;
}
th {
[ 72 ]
Chapter 1
background-color:black;
color:white;
}
td {
background-color:#19fff0;
color:black;
}"
Write-Host "CSS File Created Successfully... Executing Inventory
Report!!! Please Wait !!!" -ForegroundColor Yellow
#ReportDate
$ReportDate = Get-Date | Select -Property DateTime |ConvertTo-Html
-Fragment
#General Information
$ComputerSystem = Get-WmiObject -Class Win32_ComputerSystem |
Select -Property Model , Manufacturer , Description , PrimaryOwnerName ,
SystemType |ConvertTo-Html -Fragment
#Boot Configuration
$BootConfiguration = Get-WmiObject -Class Win32_BootConfiguration |
Select -Property Name , ConfigurationPath | ConvertTo-Html -Fragment
#BIOS Information
$BIOS = Get-WmiObject -Class Win32_BIOS | Select -Property
PSComputerName , Manufacturer , Version | ConvertTo-Html -Fragment
#Operating System Information
$OS = Get-WmiObject -Class Win32_OperatingSystem | Select -Property
Caption , CSDVersion , OSArchitecture , OSLanguage | ConvertTo-Html
-Fragment
#Time Zone Information
$TimeZone = Get-WmiObject -Class Win32_TimeZone | Select Caption ,
StandardName |
ConvertTo-Html -Fragment
#Logical Disk Information
$Disk = Get-WmiObject -Class Win32_LogicalDisk -Filter DriveType=3 |
Select SystemName , DeviceID , @{Name="size(GB)";Expression={"{0:N1}"
-f($_.size/1gb)}}, @{Name="freespace(GB)";Expression={"{0:N1}"
-f($_.freespace/1gb)}} |
[ 73 ]
[ 74 ]
Chapter 1
[ 75 ]
Chapter 1
"Script Begins"
}
Process
{
$result = $Param1 + $Param2
}
End
{
$result
}
}
This is not a good script, but I will use this to demonstrate a PowerShell function
with comments in order to help explore the use of help.
The following is an explanation of how this code works:
1. The most important part is the comment block. Let's take a look at the
following code snippet:
<#
.Synopsis
To add two integer values
.DESCRIPTION
Windows PowerShell Script Demo to add two values
This accepts pipeline values
.EXAMPLE
Add-Values -Param1 20 -Param2 30
.EXAMPLE
12,23 | Add-Values
#>
[ 77 ]
To execute this script, we need to use the .\Filename.PS1 command. Take a look at
the following image:
[ 78 ]
Chapter 1
The following is an explanation of the steps marked in the image we just considered:
1: The Get-Help cmdlet is used to get help of the custom function or script
Similarly, we can view only parameters. The help description given above each
parameter appears using the following code:
Get-Help Add-Values -Parameter *
The following are a few commands that use the help command:
help about_Functions
help about_Functions_Advanced_Methods
help about_Functions_Advanced_Parameters
help about_Functions_CmdletBindingAttribute
help about_Functions_OutputTypeAttribute
Compiled cmdlets
[ 80 ]
Chapter 1
Advanced functions
Compiled cmdlets
In this section, we will discuss both writing an advanced function code using the
PowerShell ISE and a compiled cmdlet using the Visual Studio C# class library.
Let's take a look at how to create a compiled cmdlet using the Visual Studio C# class
library. Execute the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Management.Automation;
using System.IO;
namespace Windows_Management
{
[Cmdlet(VerbsCommon.Clear, "TemporaryInternetFiles")]
public class WindowsManagement : PSCmdlet
{
protected override void ProcessRecord()
{
//Delete Internet Cache Files and Folders
string path = Environment.GetFolderPath(
Environment.SpecialFolder.InternetCache);
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Clearing Temporary Internet Cache Files
and Directories....." + path);
System.IO.DirectoryInfo folder = new DirectoryInfo(path);
foreach (FileInfo files in folder.GetFiles())
{
try
{
files.Delete();
[ 81 ]
Chapter 1
foreach (FileInfo files in folder.GetFiles())
{
try
{
files.Delete();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
foreach (DirectoryInfo Directory in folder.GetDirectories())
{
try
{
Directory.Delete();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
Console.WriteLine("Done Processing!!!");
Console.ResetColor();
}
}
}
namespace UserTemporaryFiles
{
[Cmdlet(VerbsCommon.Clear, "UserTemporaryFiles")]
public class UserTemporaryFiles : PSCmdlet
{
protected override void ProcessRecord()
{
//base.ProcessRecord();
[ 83 ]
[ 84 ]
Chapter 1
The output of the command we just discussed is illustrated in the following image:
[ 86 ]
Chapter 1
The output of the code we just discussed is illustrated in the following image:
As we have already covered the topic of adding help for PowerShell functions,
I ignored it in the advanced functions section. Remember, we do have snippets
in the ISE to create advanced functions. It's simple; just right-click on the script pane,
select Start snippet, and then choose the Advanced function complete option.
Start documenting the synopsis, description, and help for parameters and build
your code in the process block. This is very easy and handy to build advanced
scripts using PowerShell.
Before building scripts, use the Measure-Command cmdlet and think about
optimization. This will help in performance.
Summary
So far, we covered the very basics of Windows PowerShell. We now know the
importance of an object-based shell and how an ISE helps us in building scripts. We
explored the Windows PowerShell consoles and ISE snippets. After completing this
chapter, you know the power of an interactive shell, how to use cmdlets effectively,
how to use help, and the fundamentals of PowerShell along with building standard
functions and creating cmdlets using the Visual Studio class library.
In the next chapter, we will cover Common Information Model (CIM), Windows
Management Instrumentation (WMI), Extensible Markup Language, COM, .NET
objects, modules, and a more exciting section, Exploring Windows PowerShell 5.0.
[ 87 ]
www.PacktPub.com
Stay Connected: