920
CHAPTER 21
S
ECURITY
SECURITY
SECURITY
Now let’s display this credential object:
PS (3) > $cred
UserName                                                Password 
--------                                                --------
mymachine\myuserid                   System.Security.SecureString
The domain and username are stored as a regular string, but the password has been 
stored as an instance of the type 
System.Security.SecureString
. As discussed 
previously, this allows the credential object to remain in memory without presenting 
a significant security risk.
Let’s look at an example where you want to use the credential object. Let’s write a 
function called 
Start-LocalUserManager
that will start a process using different 
credentials. This works approximately like the 
runas.exe
command. You’ll use this 
function to launch the Local User Administration dialog box. When you run the 
script, you’ll see something that resembles figure 21.9.
In this example, enter the username and password for a user who hasn’t logged in 
yet, so you’ll get an error:
PS (1) > Start-LocalUserManager
cmdlet Get-Credential at command pipeline position 1 
Supply values for the following parameters: 
Credential 
Exception calling "Start" with "1" argument(s): "The user's pass 
word must be changed before logging on the first time"
At line:12 char:36 
+ [System.Diagnostics.Process]::Start( <<<< $StartInfo)
PS (2) >
Figure 21.9 Because it uses 
the 
Get-Credential 
cmdlet, when you run 
Start-LocalUser-
Manager
, you’ll see the 
credential dialog box. 
Pdf reorder pages online - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
reorder pages in pdf reader; change pdf page order online
Pdf reorder pages online - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
reorder pages in pdf online; how to reorder pages in pdf preview
U
SING
THE
S
ECURE
S
TRING
CLASS
921
Now try it again but with a valid user account. This time you see the Local User and 
Groups management console appear, as shown in figure 21.10. 
Let’s  see  how  this 
Start-LocalUserManager
function is implemented. The 
source for this function is shown in listing 21.1.
NOTE
This listing shows how the function would have to be imple-
mented in PowerShell v1. In PowerShell v2, it simply becomes a call to 
the 
Start-Process
cmdlet where most of the laborious construction 
of the 
ProcessStartInfo
object is handled by the cmdlet. The actual 
conversion to the 
Start-Process
implementation is left as an exercise 
for the reader.
function Start-LocalUserManager 
{
$cred = Get-Credential                                      
$StartInfo = New-Object System.Diagnostics.ProcessStartInfo  
$StartInfo.UserName = $cred.Username                       
$StartInfo.Password = $cred.Password                        
$StartInfo.FileName = "$env:windir\system32\mmc.exe"        
$StartInfo.Arguments = "$env:windir\system32\lusrmgr.msc"   
$StartInfo.WorkingDirectory = "$env:windir\system32"       
$StartInfo.LoadUserProfile = $true                          
$StartInfo.UseShellExecute = $false                         
[System.Diagnostics.Process]::Start($StartInfo)             
}
Figure 21.10 When you 
start the Local User Manager 
snap-in, you’ll see something 
that looks like this.
Listing 21.1    The Start-LocalUserManager function
C# TIFF: How to Reorder, Rearrange & Sort TIFF Pages Using C# Code
Reorder, Rearrange and Sort TIFF Document Pages in C#.NET Application. C# TIFF Page Sorting Overview. Reorder TIFF Pages in C#.NET Application.
pdf rearrange pages online; rearrange pdf pages online
VB.NET PowerPoint: Sort and Reorder PowerPoint Slides by Using VB.
Sort and Reorder PowerPoint Slides Range with VB amount of robust PPT slides/pages editing methods powerful & profession imaging controls, PDF document, image
how to move pages in a pdf file; reorder pages in pdf preview
922
CHAPTER 21
S
ECURITY
SECURITY
SECURITY
Because the function will prompt for credentials, you don’t need to give it any argu-
ments. The first thing you do is call 
Get-Credential
to get the credential informa-
tion that you want the process to run with. Then you create a 
ProcessStartInfo 
object that you’ll use to set the various properties you want the process to have when 
it starts. The most important of these in this example are the 
UserName
and 
Pass-
word
properties. The 
Process
object will safely decrypt the password 
SecureString 
using the 
DPAPI
when creating the process. Next you set the program you want to 
run—the Microsoft Management Console (
mmc.exe
)—and give it the path to the 
MMC
console file that will load the local user admin 
MMC
snap-in. You’re running as 
a particular user, so you want the user profile to be run and you don’t want to use 
ShellExecute
to launch the process because then you wouldn’t be able to pass the 
credentials to the underlying 
CreateProcess()
call. Once you’ve finished setting all 
the properties on the 
ProcessStartInfo
object, you call the static 
Start()
method 
on 
[System.Diagnostics.Process]
to start the process running.
Using the GetNetworkCredential() Method
Using secure strings to store passwords in the 
PSCredential
object works well when 
you’re calling an 
API
that can handle passwords stored in secure strings. Unfortu-
nately, this isn’t always the case and sometimes you need to use the password in clear 
text. You encountered this situation in section 18.6.4 while working with the Task 
Scheduler 
COM API
. As you saw in that example, the 
PSCredential
object includes 
GetNetworkCredential()
method that will return the username and password in 
clear text. Let’s quickly review how this works. First you call 
Get-Credential
to get 
the credential object:
PS (1) > $cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1 
Supply values for the following parameters: 
Credential
When you display this object, you can see the username and domain but not the 
password:
PS (2) > $cred
UserName                                                     Password 
--------                                                     --------
smith\john                               System.Security.SecureString
Now let’s call the 
GetNetworkCredential()
method and see what it shows:
PS (3) > $cred.GetNetworkCredential()
UserName                Password               Domain 
--------                --------               ------
john                    Its_a_secret           smith
Read PDF in Web Image Viewer| Online Tutorials
"This online guide content is Out Dated! Extract images from PDF documents; Add, reorder pages in PDF files; Save and print PDF as you wish;
move pages in a pdf file; pdf change page order
C# PDF: C# Code to Process PDF Document Page Using C#.NET PDF
C# PDF Page Processing: Sort PDF Pages - online C#.NET tutorial page for how to reorder, sort, reorganize or re-arrange PDF document files using C#.NET code.
pdf reverse page order; move pages in pdf file
U
SING
THE
S
ECURE
S
TRING
CLASS
923
You can see everything in clear text, including the password. At this point, some peo-
ple might wonder why you bother with secure strings at all if it’s so easy to get the 
data back. The thing to remember is that you typed in the password in the first place 
so it isn’t telling you anything you don’t already know. As discussed in section 21.5.1, 
the intent is to minimize the amount of time the password is exposed as clear text, 
thereby minimizing the amount of time it might be captured during a crash dump or 
hibernate.
You now have a good working knowledge of secure strings and credentials, but 
these technologies by themselves don’t guarantee security. If an exploitable vulnera-
bility exists in the script itself, all your careful credential management will be useless. 
Let’s look at some things you need to be particularly aware of when trying to write 
secure scripts.
21.6.4
Avoiding Invoke-Expression
At the beginning of this chapter, we talked about the risks of using the 
Invoke-
Expression
cmdlet and code injection attacks in general. If you can avoid using this 
cmdlet, it’s a good idea for two reasons: first, not using it makes your code less vulner-
able, and  second, 
Invoke-Expression
has performance consequences because it 
requires that the expression be recompiled every time it gets called. In most circum-
stances,  it’s  possible  to  rewrite  your  code  using scriptblocks  instead  of 
Invoke-
Expression
.
WARNING
If  you  use  the  features  described  in  section  13.2.5, 
Invoke-Expression
is one cmdlet that should always be omitted 
from that session configuration. You should also be careful with any 
code in a constrained session that uses 
Invoke-Expression
and make 
sure that a thorough security review of that code is done.
In this section, we’ll work through a real example where you take a piece of script 
code using 
Invoke-Expression
and rewrite it to use scriptblocks.
The original wheres script
The idea behind this script was to come up with a version of the 
Where-Object 
cmdlet that had a simpler syntax. The function was created by one of the developers 
on the PowerShell team. Instead of typing a command line that looked like this
PS (3) > dir | where {$_.extension -eq ".ps1"}
Directory: Microsoft.PowerShell.Core\FileSystem::C:\Temp
Mode                LastWriteTime     Length Name 
----                -------------     ------ ----
-a---         8/13/2006   5:44 PM       3250 test-script.ps1
VB.NET TIFF: Modify TIFF File by Adding, Deleting & Sort TIFF
Users can use it to reorder TIFF pages in ''' &ltsummary> ''' Sort TIFF document pages in designed powerful & profession imaging controls, PDF document, image
how to reorder pdf pages in reader; move pages in pdf reader
C# PDF Page Rotate Library: rotate PDF page permanently in C#.net
Online C# class source codes enable the ability to rotate single NET, add new PDF page, delete certain PDF page, reorder existing PDF pages and split
how to move pages around in pdf file; reorder pages in pdf
924
CHAPTER 21
S
ECURITY
SECURITY
SECURITY
he wanted to simply type
PS (1) > dir | wheres extension eq .ps1
Directory: Microsoft.PowerShell.Core\FileSystem::C:\Temp
Mode                LastWriteTime     Length Name 
----                -------------     ------ ----
-a---         8/13/2006   5:44 PM       3250 test-script.ps1
There’s certainly a lot less punctuation in the second command line, so it seems a 
worthy goal. The original version of the command is shown in the following listing.
function wheres($property, $operator, $matchText)                
{
begin { 
$expression = "`$_.$property -$operator `"$matchText`""          
}
process {
if( Invoke-Expression $expression)                        
{
$_
}
}
This function takes three parameters—the property on the inbound pipeline object 
to check, the operation to perform, and the value to check against. In the 
begin 
clause of the function, you precalculate as much of the expression as possible, expand-
ing the property name and the operator into 
$expression
. This gets rid of the string 
expansion step that would otherwise be performed for each pipeline object. Finally, in 
the 
process
clause of the function, 
Invoke-Expression
is used to evaluate the 
expression for the current pipeline object and emit the object if it matches.
This is a straightforward implementation of the function, but there’s one worri-
some aspect. Executing a command such as the following is fine
dir | wheres mode match d
but something like this
dir | wheres extension eq '.ps1"; Write-Host hi; "'
will both interfere with the results you expect and execute the extra code 
Write-Host 
hi
. If the extra code were something like 
del –Force –Recurse c:\
, then it’d be 
more than merely annoying.
Of course, the author of this script would never do anything like this. But some-
one else who’s just using the script might think it’s safe to pass untrusted arguments 
to it. After all, looking at it from the outside, there are no obvious code injection vul-
nerabilities. It appears to accept a simple operator, nothing more. This is why you
Listing21.2    The original wheres function
C# Word: How to Create Word Document Viewer in C#.NET Imaging
Offer mature Word file page manipulation functions (add, delete & reorder pages) in document viewer; (Directly see online document viewer demo here.).
reorder pages pdf file; move pdf pages online
VB.NET TIFF: VB.NET Sample Code to Process & Manage TIFF Page
certain TIFF page, and sort & reorder TIFF pages in Process TIFF Pages Independently in VB.NET Code. powerful & profession imaging controls, PDF document, image
change page order pdf preview; move pages in pdf
U
SING
THE
S
ECURE
S
TRING
CLASS
925
need to be cautious with this kind of script—because of the cascading consequences 
problem we discussed at the beginning of the chapter. This script appears on a blog, 
gets copied into someone else’s application, which gets copied into a third individ-
ual’s web application, and now this script that was never intended to be used with 
untrusted input is being used for exactly that in a network-facing application. Not a 
good situation. Let’s see what you can do to make the script more robust and also run 
faster at the same time.
A safer, faster wheres script
The problem with the old script was that it used 
Invoke-Expression
to evaluate an 
expression at runtime. You want to use scriptblocks to be a bit more static in your 
approach. The solution is shown here.
function wheres 
{
begin {
if ($args.count -ne 3)           
throw "wheres: syntax <prop> <op> <val>"
}
$prop,$op,$y= $args
$op_fn = $(                                               
switch ($op)                                          
{
eq      {{$x.$prop -eq $y}; break}   
ne      {{$x.$prop -ne $y}; break}
gt      {{$x.$prop -gt $y}; break}
ge      {{$x.$prop -ge $y}; break}
lt      {{$x.$prop -lt $y}; break}
le      {{$x.$prop -le $y}; break}
like    {{$x.$prop -like $y}; break}
notlike {{$x.$prop -notlike $y}; break}
match   {{$x.$prop -match $y}; break}
notmatch {{$x.$prop -notmatch $y}; break}
default {                               
throw "wh: operator '$op' isn't defined"
}
}
)
}
process { $x=$_; if( . $op_fn) { $x }}     
}
In this version of the function, you begin by validating the number of arguments 
B
and reporting an error if there aren't three arguments. You want to place a scriptblock 
in the variable 
$op_fn
, which you’ll use to implement the processing for that opera-
tor. You use a 
switch
statement to select the right scriptblock to return. There’s one
Listing 21.3    The safe wheres function
Validate 
arguments
b
Implement EQ
c
Throw error 
on unknown 
operator
d
Invoke operator 
function
e
926
CHAPTER 21
S
ECURITY
SECURITY
SECURITY
scriptblock for each operator; for example, the 
eq
operator is shown in 
c
. If the 
operator isn’t one of the ones you’ve chosen to implement, you’ll throw an error 
d
Once you’ve selected the scriptblock, you’ll invoke it 
e
once for each inbound 
pipeline object. Notice that you don’t pass any arguments to the scriptblock. Dynamic 
scoping allows the scriptblock to pick up the arguments from the enclosing scope.
This second implementation  is  clearly more  complex,  but  it does  more  error 
checking, is more robust in general, and has no code injection vulnerabilities. It’s also 
significantly faster than the 
Invoke-Expression
version. (It also makes a good illus-
tration of the use of scriptblocks.)
There are many more examples where you can replace 
Invoke-Expression
with 
scriptblocks, but in the end, the approach is basically the same—decide whether you 
really need to generate code at runtime or whether you can just select from a set of 
precompiled alternatives. If the set of alternatives is large, you may want to use a 
hashtable instead of a 
switch
statement, but the principle remains the same.
This brings us to the end of our discussion of security and PowerShell. Securing 
systems and writing secure code can be a subtle, twisty, and arcane topic. It can also 
be alternately completely fascinating or as dull as toast.
21.7
S
UMMARY
Let’s review what we covered in this chapter. We began with a rant (sorry—discus-
sion) on security and threat modeling. We discussed:
• What security is—mechanisms for operating a computer without the risk of 
danger or loss
• That  security  isn’t  equivalent  to  cryptography  and  its  related  technologies 
(although these tools are used to build a secure system)
• Basic threat modeling and the 
STRIDE
approach
• Definitions for the elements of a threat model: vulnerability, threat, asset, and 
mitigation
In  the  next  section,  we  covered  securing  the  PowerShell  installation  itself.  This 
included discussions of how PowerShell is secure by default. As installed, PowerShell 
limits its attack surface by
• Having no default file association; this prevents use of attachment invocation or 
point-and-click social engineering attacks.
• Exposing no remote access endpoints, forcing a hopeful attacker to depend on 
other tools.
• Having a default execution policy of 
Restricted
, which prevents any scripts 
from running. 
• Not including the current directory in the command search path, preventing 
working directory exploits.
S
UMMARY
927
• Additional issues around managing the execution path.
• Execution policy—what it is and how you can examine the current execution 
policy using 
Get-ExecutionPolicy
. To allow signed scripts to run, use 
Set-
ExecutionPolicy AllSigned
, and to allow any local scripts to run—the loos-
est reasonable policy—use 
Set-ExecutionPolicy
RemoteSigned
.
• Script signing—how it works and how to set up certificates, keys, and so on.
The final part of the chapter explored technologies and techniques you can use for 
making your scripts more robust. The topics included
• The fact that you should always store sensitive information in memory using 
the .
NET
SecureString
class and that you can read data as a secure string from 
the keyboard using the 
Read-Host
cmdlet
• Working with credentials and using the 
Get-Credential
cmdlet
• Approaches for avoiding the use of 
Invoke-Expression
in scripts
Computer  security  is  a complex, evolving  field.  It’s obviously important to keep 
abreast  of the latest tools and techniques, as well as monitor the current crop of 
threats and exploits. Thinking through a problem can be facilitated by tools and 
models, but in the end, there’s no replacement for common sense.
You’re done with your journey through the PowerShell world. It’s been a rather 
long journey—the scope and range of what can be done with PowerShell can be both 
dazzling and daunting at times. But always remember that PowerShell is a tool cre-
ated for you, the user. Don’t be afraid to experiment with it, play with it, and then 
apply it. To quote Jeffrey Snover, the inventor of PowerShell:
All you need to do is to learn what you need to accomplish the task at 
hand…and a bit more. Then do it again. And again. And again. Have 
fun with it and push the envelope.
928
CHAPTER 21
S
ECURITY
SECURITY
SECURITY
929
index
Symbols
--symbol 41 
./ prefix 45 
.\ prefix 45 
(see!) argument 228 
@ symbol 37, 95 
@( ... ). See  array subexpressions 
& operator 415 
& symbol 37 
# character 58 
% alias 684 
+ symbol 59 
+= operator 685 
> operator 181 
>> operator 181 
$_ variable 37, 217–218, 224, 265, 572, 677 
$? variable 564–565, 621, 794 
$( ... ). See  subexpressions 
$count variable 379 
$error variable 560–561
Numerics
2> operator 181 
2>&1 operator 181 
2>> operator 181 
32-bit applications, 64-bit applications vs. 793 
32-bit operating systems 499 
64-bit applications, vs. 32-bit applications 793 
64-bit operating systems 499
A
abstraction 8 
access controls, and endpoints 533–535 
access restriction 543 
access to current tab 623 
accessing COM objects 767 
AccessMode module 388 
accidental code injections 439 
accidental execution 276 
accumulated results, in variables 208 
acronyms 37 
-Action parameter 855 
Action parameter 842 
Action property, on PSBreakpoint object 654 
action script block, in breakpoints 658 
actions
asynchronous events 854 
running upon module removal 389–391
Actions.Create() method 789 
Active Directory Services Interface (ADSI) 75 
active scope 652 
ActiveScript engine 783 
ActiveX Data Objects (ADO) 75 
adaptation 761
extending objects 401 
of existing member 427 
synthetic members 402
adaptation layer, COM 762 
adapter mechanism 77 
add members 401 
add property 405
Documents you may be interested
Documents you may be interested