PDF Archive

Easily share your PDF documents with your contacts, on the Web and Social Networks.

Share a file Manage my documents Convert Recover PDF Search Help Contact

FunctionsParamADUsers .pdf

Original filename: FunctionsParamADUsers.pdf
Author: dhr

This PDF 1.3 document has been generated by http://www.convertapi.com, and has been sent on pdf-archive.com on 08/12/2016 at 01:11, from IP address 74.14.x.x. The current document download page has been viewed 463 times.
File size: 2.9 MB (33 pages).
Privacy: public file

Download original PDF file

Document preview

Lecture 10 – Functions Continued

Page 1 of 33

Lecture 10 Functions Continued and User
Last week we learned about function syntax, writing
help files, error checking, and passing named and
unnamed parameters and setting default values. This
week we will learn about scopes, the param keyword
and setting attributes for functions, such as making
parameters mandatory. We will also learn about how
to use the new AD cmdlets to create user and manage user accounts.

A “scope” is a security container which protects objects from being modified, intentionally or
unintentionally by a running script or function. Scripts and functions run in the local scope environment
can only change objects in the current scope, such as: Variables, Aliases, Functions and PowerShell
Drives (PSDrives). New scopes are created whenever you run a script or function, or when you create a
new session or instance of PowerShell. Scopes created by running scripts and functions have a
“parent/child” relationship with the scope from which they were created. There are a few scopes that
have particularly special meanings, and can be accessed by name:

The Global scope is the scope that is created when PowerShell starts. It includes the variables,
aliases, functions, and PSDrives that are built-in to PowerShell as well as any which are made by
your PowerShell profile.

The Local scope refers to whatever the current scope is. When you start PowerShell it will refer
to the Global scope, within a script it will be the Script scope, etc.

The Script scope is created when a script is run. The only commands that operate within this
scope are those that are in the script.

Private scopes can be defined within the current scope, to prevent commands in other scopes

Global Scope
Script Scope

Figure 1: Diagram of Scopes

© Seneca College, ICT, 2013


Lecture 10 – Functions Continued

Page 2 of 33

from being able to read or modify items they might otherwise have access to.
When you open the PowerShell console and type at the command line, your local scope is the global
scope. The current scope is referred to as zero and its ancestors are referenced by increasing integers.
For example, if you run a script from the command line, then your local scope is the script scope; the
latter would be 0 and the Global scope would be 1. Then if you run a function, the local scope would be
a function scope and the Global scope would be referred to as 2.
Scopes and Commands
As mentioned earlier, commands executed within one scope will not affect things in another scope
unless explicitly told to do so. For example, if $Variable1 exists in the Global scope and a script runs a
command to set $Variable1 to a different value, the Global version of $Variable1 will remain unaltered
while a copy of $Variable1 is placed in the Script scope with the new value. If a $Variable1 doesn’t exist,
a script will create it within the Script scope by default – not in the Global scope. This is important to
remember as you learn about the actual parent/child relationship between scopes.
The parent/child relationship of scopes in PowerShell is one-way. Commands can see into, and
optionally modify, the current scope, its parent, and any scopes above that. However, they cannot see
or modify things in any children of the current scope.
There are plenty of times where you need a script’s or function’s changes to persist beyond its
completion. This is why functions must be dot-sourced. The latter copies any variables, such $Variable
1 to the Global scope, so it would be available to another function running in the same session.
One exception to the above is a Private scope. Objects in a Private scope are only accessible to
commands run in the scope from which
they were created.
Scopes in Action
To see how scopes work, we will write a
short script called scope-demo.ps1.
Before running your script, type the
following at the command line.
$variable1 = “I am a global variable”.
This will make $variable1 a global
variable, since we are creating it at the
console. Note: this script must be run
from the PowerShell console, DO NOT
use the ISE you will not get the correct
Figure 2: Code to Test Scopes

© Seneca College, ICT, 2013

Type the following code into your ISE,
but run the script from the command

Lecture 10 – Functions Continued

Page 3 of 33

The script first gets the value of $variable1. Since $variable1 was not defined in the script scope,
PowerShell automatically goes up the scope tree to find the value. It finds the value in the global scope
and displays: “I am a global variable”.
The script, in the script scope, then changes the value of $variable1 to “I am a script variable”. And then
calls the function scope-demo.
The function scope-demo did not find a value for $variable1 in the function scope, so it climbed the
scope tree and found $variable1 in the script scope and displayed: “I am a script variable”. The value of
$variable1 was changed and the new value inside the function is displayed: “I am a function variable”.
When the function ends, however, the value of $variable1 is lost, and the only value PowerShell can find
is in the script scope, so it displays: “I am a script variable” before the script exits. At the command
prompt, however, if you type $variable1, you will notice that the value is “I am a global variable”
because the global variable was not changed. Child scopes can read, and modify values above the
current scope, but can’t change values in children of the current scope.

Figure 3: Output of Scope-Demo.ps1

In writing PowerShell scripts or functions it is a bad practice to declare a variable and not define its value
within the local scope, because PowerShell will climb the scope tree to assign a value for a variable of
the same name. This could be a problem and cause unexpected problems in your script or function.
Best practice is always to declare variables and assign values in the local scope. Notice how the scopes
worked. $Variable1 was changed as we moved through the script because, up until the Function ScopeDemo was completed, we were checking on the variable from within the same scope it was last
changed. After the Function ended, we moved back into the Script scope where $Variable1 was left
untouched by the function. Then, when the script terminated, we came back out into the Global scope
where the global variable $variable1 hadn’t been modified at all.
Reaching Outside the Local Scope
It is generally regarded as bad practice to modify variables outside of the local scope, but it can be done
using a special, and fairly simple, syntax:
© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 4 of 33

Let’s see what happens with this demonstration script scope-demo2.ps1. Copy the code from the
scope-demo script to a new tab in the ISE.
As before, we’ll start by setting the variable1 value at the command line to “I am a global variable”.
The script starts by
getting the current
value of $variable1,
which it finds by
climbing the scope
tree, in the global
scope. The text “I am
a global variable” is
The script then
changes the value of
$variable1 in the
script scope to “I am
a script variable”.
The function scopeFigure 4: Code for Scope-Demo2.ps1: Changing variables out of scope

demo is called and
the variables in each
scope are explicitly
changed and then
displayed. When the
function ends, the
script scope variable
has been changed as

Figure 5: Output of Scope-Demo2: Explicitly changing variables out of scope

well as the global
scope variable.

To prevent the changing of a variable in the current scope, and make if invisible,(even when using the
Get-Variable cmdlets) we change the nature of the variable using the keyword private.
Open a new console window and type the following:
Type: New-Variable –name Variable1 –value 1000 –option private
Type: $variable1 = 1

© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 5 of 33

Notice we created a private variable and assigned a value of 1000 to it in the global scope. We were
able to change the value of the variable to 1 in the current scope.
Open a new tab in the ISE and type the following. Call the new file scope-demo3.ps1
"The value of `$variable1 is $variable1"
"The value of `$variable1 is $global:variable1"
This script attempts to read the private console variable; private variables are inherited by the child
scope; they are visible and can be modified only in the scope in which they were created. Consequently,
the values are empty when the script runs which is in the script scope.
Dot-sourcing a function is done by placing a dot in front of the path. For example:
. .\scope-demo4.ps1
You are telling PowerShell to load the function into memory and to copy any variables in the function to
the global scope, so they will be available to other functions running in the same session. By dotsourcing the functions at the top of the script, we can use the function name only in the option script
block of the switch statement and any parameters would be available to other functions. We can see
how this works by creating a script Scope-Demo4.ps1.

Figure 6: Suspending Scope-Demo4 to view Global variables

Type: . .\scope-demo4.ps1
Type: Scope-Demo
Type: S for suspend
Type: GetVariable name
The function
creates one
parameter called
name with the
value of
Figure 7: Function variable Name copied to Global scope

© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 6 of 33

When the function runs the confirm parameter provides a menu. Pressing “S” suspends the current
shell and creates a nested child shell which inherits the information from the parent shell. This allows us
to use the get-variable command which shows that the name parameter has been copied from the
function scope to the global scope.
Using Functions for Common Administrative Tasks
A very common task for administrators is to check system’s name and version number to ensure that
software, such as scripts and applications will run correctly. We will use WMI to retrieve the operating
system name and version numbers. First, we must decide a name for this function. Based on the verbnoun PowerShell format, we will call this function Get-OsVersion. Open a new tab in PowerShell ISE and
copy and paste the following:
Function Get-OsVersion {
Get-WmiObject -Class Win32_OperatingSystem | Select-Object -property Name,Version
} #end Get-OsVersion
To run the function we must first tell PowerShell to load the function into memory. To do this we use
the dot sourcing method. Once the function is loaded into memory, typing the function’s name
executes the script.

Figure 8: Using Dot Sourcing to Execute OsVersion Function

The OsVersion function is helpful, but it is a specific purpose function since the WMI class and name and
version properties are “hard-coded” into the script. Parameters can make functions more useful by
allowing the user to change the class and properties on the fly.
Using Param
Last week we defined parameters outside of the script block by enclosing them in parenthesis. This
week we will use the PARAM keyword to create parameters inside the script block. The syntax for using
function <name> {
param ([type]$parameter1[,[type]$parameter2])
<statement list>
There is no difference between these two methods of defining parameters. Use the method that you
prefer. However, when you have parameters with many attributes, param makes them easier to read.
© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 7 of 33

Another common administrative function is to display properties of a device. We will modify the
OsVersion function by adding 3 parameters to run this specific purpose function. Open a new tab in
PowerShell ISE and copy all of the code from OsVersion function into the new tab. Name the new file
Get-DeviceInfo.ps1 and the name the new function Get-DeviceInfo
Function Get-DeviceInfo
Get-WmiObject -Class Win32_OperatingSystem | Select-Object -property Name,Version
} #end of Get-DeviceInfo
Your code should look like the above. Now we will add mandatory parameters using the param keyword
and include a help message to the user on the purpose of the parameter. Inside the script block begin
the line with the param keyword. Copy and paste the following code into your Get-DeviceInfo function
param (
[parameter(Mandatory = $true, HelpMessage = “Enter a WMI class name:”, Position = 1)]
[string] $WMIClass,
[parameter(Mandatory = $true, HelpMessage = “Enter a device property name1:”, Position = 2)]
[parameter(Mandatory = $true, HelpMessage = “Enter a device property name2:”,Position = 3 )]
Notice the syntax. The param keyword must be on its on line. The parameters must be enclosed in
parenthesis. Since we are making these three parameters mandatory, the keyword parameter must be
used and enclosed in square brackets. Mandatory = $true statement ensures that if the user does not
enter the parameter on the command line, he/she will be prompted to do so. This feature avoids having
to provide parameter error checking like we did last week.
The Position attribute ensures that the user enters the parameters in the correct order on the command
line, if they are not named. PowerShell will interpret the first position as the class and position 2 and 3
as properties. Notice that each attribute is separated by a comma. The line ends with the closing
square bracket. The next line identifies the parameter type and name just like a variable. When the
parameter attributes have been described, a comma is used to separate each parameter, except the last
one. This syntax makes reading the code and identifying any errors easier. Now we need to change the
Get-WMIObject line to use the parameters. Change the line to that below:
Get-WmiObject -Class $WMIClass | Select-Object -property $property1,$property2

© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 8 of 33

Figure 9: Output of the General Purpose Get-Device Info Function

Notice the help message which helps to describe the purpose of the parameter. Since no parameters
were entered on the command line, the user was prompted for each named parameter. In the second
execution of the function, the parameters were entered on the command line, after the functions name,
and resulted in completely different output. With use a few lines of code we have changed a specific
purpose function to a flexible general purpose function using named parameters.
A filter is identical to a function, except the filter keyword is used. A function uses the $input variable to
contain pipeline information whereas the filter uses a special variable $_ that contains the current
pipeline object. With the $input variable the function doesn’t run until all data has been stored in
the$input variable, whereas the filter has immediate access to the $_ variable and begins processing
elements as they become available (streaming). This makes filters more memory efficient when large
amounts of data are passed through the object pipeline.

Using the
MeasureCommand we
can see that
even with this
small collection
in the pipeline
the filter is 59%
Figure 10: Using the Measure-Command to compare Filter to a Function
faster, 13
milliseconds as opposed to 22 milliseconds. The larger the collection in the pipeline, the more efficient a
filter will be.
Switch Parameters
A switch parameter is used when you need to have a Boolean value as a parameter. It does not require
a value. Instead, you type the function name followed by the name of the switch parameter. When you
declare a parameter as a switch parameter, its value is set to $False. Using whatever logic you like, you
can test to see if the condition became $True when the user executed the function and specified the
© Seneca College, ICT, 2013

Lecture 10 – Functions Continued

Page 9 of 33

parameter. Let’s look at a simple example: To define a switch parameter, specify the type [switch]
before the parameter name, as shown in the following example:
We will write a function which will count an array of server names. There are 10 server names, but
server2 name is repeated 3 times in the set. The function will have two parameters an array called
name and a switch called num.
function CountSrv ([array]$Name,[switch]$num){
$input = @("server1","server2","server3","server4","server2","server5","server6",`
$input | ForEach {"$_ ;$($count++)"}
if ($num -eq $true) {$server2 = 3}
$count = 0
$server2 = 0
Write-Host $count $server2
The first time we run
CountSrv with not
parameters the server
count is 10 and the
server2 count is 0
because that is the
value we had set.
However, when we ran the function again with the –num parameter, the if statement became true and
the server2 count was
Figure 11: Using the Switch Parameter
incremented to 3.
The switch parameter
can be used for troubleshooting or testing if a condition has changed.

Active Directory User Management
Last week we discussed installing ADDS. This week we will look at how to manage user accounts using
groups, and organizational units. All of the AD cmdlets are in a module called Active Directory. To use
the cmdlets, you must
first import the activedirectory module into
the session.
To view modules
currently installed:
Type: get-module
Many of the cmdlets we
Figure 12: Viewing available modules

© Seneca College, ICT, 2013

Related documents

win213r test1 review2016 02 19 1
powershell for newbies getting started powershell4

Related keywords