LabGuide Beta PDF
LabGuide Beta PDF
COPYRIGHT*LICENSE*
!
The!author!of!this!document,!Concentrated!Technology!LLC!(“Licensor”)!grants!you!(“Licensee”)!the!
right!to!reproduce!this!document!electronically!and!physically,!subject!to!the!following!terms!and!
conditions:!
• You!must!duplicate!the!entire!document,!asAis,!with!no!changes,!deletions,!additions,!or!
alterations,!including!this!License.!
!
• You!may!not!use!this!document!as!part!of!a!commercial!training!class!where!students!have!
paid!a!fee!to!take!the!class.!
!
• Licensor!provides!no!remedies!or!warranties,!whether!express!or!implied,!for!anything!
contained!in!this!document.!Everything!is!provided!“as!is.”!Licensor!disclaims!all!warranties!
and!representations,!whether!express,!implied,!or!otherwise,!including!the!warranties!of!
merchantability!or!fitness!for!a!particular!purpose.!Also,!there!is!no!warranty!of!nonA
infringement,!title,!or!quiet!enjoyment.!Licensor!does!not!warrant!that!this!document!is!
errorAfree.!!
!
• You!may!not!post!electronic!copies!of!this!document!in!any!publicly!accessible!location.!
Instead,!refer!other!parties!to!the!original!location!where!you!obtained!this!document.!
!
• NEITHER*LICENSOR*NOR*ITS*SUPPLIERS*SHALL*BE*LIABLE*TO*YOU*OR*ANY*THIRD*
PARTY*FOR*ANY*INDIRECT,*SPECIAL,*INCIDENTAL,*PUNITIVE,*COVER*OR*
CONSEQUENTIAL*DAMAGES*(INCLUDING,*BUT*NOT*LIMITED*TO,*DAMAGES*FOR*THE*
INABILITY*TO*USE*EQUIPMENT*OR*ACCESS*DATA,*LOSS*OF*BUSINESS,*LOSS*OF*
PROFITS,*BUSINESS*INTERRUPTION*OR*THE*LIKE),*ARISING*OUT*OF*THE*USE*OF,*OR*
INABILITY*TO*USE,*THIS*DOCUMENT*AND*BASED*ON*ANY*THEORY*OF*LIABILITY*
INCLUDING*BREACH*OF*CONTRACT,*BREACH*OF*WARRANTY,*TORT*(INCLUDING*
NEGLIGENCE),*PRODUCT*LIABILITY*OR*OTHERWISE,*EVEN*IF*LICENSOR*OR*ITS*
REPRESENTATIVES*HAVE*BEEN*ADVISED*OF*THE*POSSIBILITY*OF*SUCH*DAMAGES*
AND*EVEN*IF*A*REMEDY*SET*FORTH*HEREIN*IS*FOUND*TO*HAVE*FAILED*OF*ITS*
ESSENTIAL*PURPOSE.*YOU*AGREE*THAT*YOU*HAVE*PAID*NOTHING*FOR*THIS*
DOCUMENT*AND*ARE*NOT*ENTITLED*TO*DAMAGES.!
!
!
!
!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
Note%that%this%Lab%Guide%may%have%been%created%
specifically%for%your%class%delivery.%It%may%not%include%
all%available%units,%and%your%instructor%may%not%cover%units%
in%numeric%order.%Unit%numbers%are%for%reference%
only,%and%are%not%intended%to%suggest%a%delivery%sequence.%
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Windows
PowerShell
Lab Guide
by Don Jones
v14.1
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Welcome
This!lab!guide!is!designed!as!an!inAclass!companion!for!Concentrated!Tech!classes!on!Windows!
PowerShell.!!
Please!note!that!this!lab!guide!was!customized!for!your!class.!Therefore,!unit!numbers!may!not!be!
sequential,!and!may!not!be!in!order.!Unit!numbers!are!for!reference!only,!and!do!not!indicate!a!
particular!delivery!sequence.!
• This!lab!guide!works!best!when!paired!with!Learn%Windows%PowerShell%in%a%Month%of%Lunches!
and!Learn%PowerShell%Toolmaking%in%a%Month%of%Lunches.%Both!books!are!available!from!
http://manning.com.!!
!
• For!additional!reference!material!and!inAdepth!coverage,!consider!PowerShell%In%Depth,%also!
from!http://manning.com.!!
!
• Specific!units!of!this!lab!guide!can!be!supplemented!with!the!free!ebooks!available!at!
http://powershell.org/wp/forums.!!
!
• You!may!also!wish!to!subscribe!to!the!PowerShell.org!TechLetter,!at!
http://powershell.org/wp/newsletter.!The!TechLetter!offers!free!monthly!feature!articles,!
PowerShell!community!news,!and!more.!It!also!notifies!you!of!upcoming!live!TechSession!
webinars,!and!provides!access!to!recordings!of!past!TechSession!webinars.!
!
• AfterAclass!Q&A!should!be!posted!in!the!PowerShell!Q&A!or!DSC!forums!at!
http://powershell.org.!!
!
Answer Key
This!Guide!does!not!include!an!answer!key.!Most!things!in!PowerShell!can!be!correctly!accomplished!
in!many!different!ways,!and!no!one!way!is!necessarily!“right”!or!“wrong.”!If!you!have!questions!about!
your!particular!solution,!or!if!you!cannot!come!up!with!a!solution!to!a!task,!please!ask!your!
instructor.!
!
Version Differences
These!labs!mostly!expect!that!you!are!running!the!latest!copy!of!Windows!and!the!latest!version!of!
Windows!PowerShell.!However,!the!labs!all!note!the!minimum!version!of!Windows!and!PowerShell!
required!to!complete!that!lab.!Those!notations!are!designed!to!help!you!quickly!identify!labs!that!rely!
on!functionality!from!a!particular!version.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Lab Setup
This!setup!section!assumes!that!you!are!already!familiar!with!Windows!operating!system!
installation,!basic!virtualization!concepts,!etc.!If!you!are!not!familiar!with!these,!then!Windows!
PowerShell!may!be!too!advanced!a!topic!for!you!to!tackle.!
Your!computer!must!have!at!least!4GB!of!memory!–!although!more!is!better.!You!will!need!
approximately!40GB!of!free!disk!space.!Your!computer!must!have!a!64Abit!processor,!and!must!be!
running!a!64Abit!operating!system.!
32?bit*computers*will*not*work.*Host*computers*with*less*than*4GB*of*memory*will*probably*
not*work,*although*we’ve*seen*folks*pull*it*off*in*2GB*when*they*were*patient.*
You!Will!Need!a!Virtualization!Product!
• If!you!are!running!Windows!7,!we!suggest!using!the!free!VMware!Player!application!
(https://my.vmware.com/web/vmware/free#desktop_end_user_computing/vmware_playe
r/6_0).!You!may!also!use!VMware!Workstation!or!VMware!Fusion.!You!will!need!the!latest!
versions!of!these!products!–!please!upgrade!if!necessary.!
!
• If!you!are!running!Windows!8!or!later,!we!suggest!installing!the!builtAin!HyperAV!feature!
(including!tools).!You!can!also!use!VMware!Player.!
!
Caution!
If!you!plan!to!use!trial!software,!be!aware!of!its!expiration!period.!Make!sure!you!don’t!set!up!the!VMs!
so!far!in!advance!that!they’ll!expire!before!the!end!of!your!class.!
!
Instructions!
1. You!will!need!to!download!our!class!ISO!image!from!http://1drv.ms/QoVGdb.!You!will!also!
need!installation!media!for!Windows!Server!2012!R2!(Datacenter!ISO,!from!
http://technet.microsoft.com/enAus/evalcenter/dn205286.aspx)!and!Windows!8.1!(64Abit,!
from!http://technet.microsoft.com/enAus/evalcenter/hh699156.aspx).!!
!
These!images!are!big.!Make!sure!you!allow!time!to!download!them!all.!
!
If!you!already!have!Windows!Server!2012!R2!or!Windows!8.1!installation!media,!you!are!
welcome!to!use!that!instead!of!downloading!the!above.!You!will!still!need!to!download!our!
class!ISO!image.!
!
2. Configure!the!virtual!machines!as!follows:!
• 512MB!of!memory!for!Windows!Server!2012!R2;!1024MB!of!memory!for!Windows!8.1.!
If!your!system!can!spare!it,!1536MB!of!memory!or!even!2048MB!for!Windows!8.1!will!
work!better.!
• 30GB!of!virtual!disk!space!
• Configure!the!virtual!machine!network!so!that!the!VMs!can!only!talk!to!each!other:!
o In!HyperAV,!create!a!virtual!network!switch!that!is!of!the!type!“Internal.”!
Connect!each!virtual!machine’s!network!adapter!to!this!virtual!switch.!
o In!the!VMware!products,!configure!the!virtual!machines’!network!adapters!to!
“host!only”!or!something!similar.!!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
3. Start!the!installation!for!both!Windows!8.1!and!Windows!Server!2012!R2.!Accept!all!
installation!defaults,!including!the!default!Server!Core!installation!for!Windows!Server!2012!
R2.!!
• You!will!be!prompted!for!license!keys.!You!can!use!the!ones!that!Microsoft!sent!you!after!
you!registered!for!the!trial.!We!do!not!provide!product!keys.!
• Use!Pa$$w0rd!for!all!passwords.!Windows!8.1!may!want!you!to!set!up!a!Microsoft!
Account;!just!agree!to!do!so,!and!then!cancel.!You!don’t!need!a!Microsoft!Account!in!this!
virtual!machine.!See!later!in!this!guide!for!Windows!8.1!instructions.!
• You!can!name!the!computers!whatever!you!like!–!our!script!will!rename!them!to!CLIENT!
and!DC,!and!they’ll!join!the!LAB.PRI!domain.!
!
4. After!installation!is!complete,!VMware!users!should!install!the!Virtual!Machine!Additions.!In!
Server!Core,!you!may!have!to!let!VMware!attach!the!ISO!image,!and!then!change!to!the!VM’s!
D:!drive!to!manually!run!the!64Abit!setup.!
!
5. If!you!plan!to!run!Windows!Update!or!activate!Windows,!you!should!do!that!now.!You’ll!need!
to!modify!the!Virtual!Switch!(HyperAV)!or!VM!settings!(VMware)!so!that!the!VMs’!network!
adapter!can!use!your!host!computer’s!Internet!connection.!When!you’re!done,!be!sure!to!set!
the!networks!back!to!Internal!(HyperAV)!or!Private/HostAOnly.!Our!setup!script!will!be!
assigning!static!IP!addresses!to!the!virtual!machines,!and!you!don’t!want!those!conflicting!
with!anything!else!on!your!network.!None%of%this%is%required%–%only%do%it%if%you%plan%to%keep%the%
VM%around%for%a%long%time.!
!
6. When!you’re!all!done!installing!Windows!and!whatnot,!attach!our!PowerShell.iso!image!to!
the!virtual!DVD!drive!of!each!virtual!machine.!!
!
7. On!the!Windows!Server!2012!R2!VM,!open!a!Windows!PowerShell!console!“as!
Administrator,”!and!run!the!following:!
PS#C:\>#Set*ExecutionPolicy#Bypass#
PS#C:\>#D:\SetupLab.ps1#
Note:!On!Server!Core,!just!run!powershell!to!switch!to!PowerShell.!Then!run!the!above!two!
commands.!
!
Our!setup!script!will!prompt!for!several!pieces!of!information,!including:!
• Your!DVD!drive!letter!(usually!D:!and!be!sure!to!include!the!colon)!
• If!you’re!prompted!to!install!the!hotfix,!answer!Yes.!
• If! you’re! prompted! to! restart,! do! so.! If! the! restart! is! immediately! after! the! hotfix!
installation,!you’ll!need!to!log!in,!enter!PowerShell,!and!run!D:\SetupLab!again.!
• A!password!or!two!–!use!Pa$$w0rd!every!time!
The! script! may! need! to! install! the! KB2883200! hotfix! (which! it! has! on! the! ISO! image).! If!
you’re!prompted!for!any!passwords,!use!Pa$$w0rd.!Setup!may!take!a!while!to!complete!–!be!
patient.!
!
For! the! server,! you’ll! know! you’re! done! when! it’s! at! the! “Press! Ctrl+Alt+Del”! screen,! and!
you’re!able!to!log!on!as!LAB\Administrator.!That!tells!you!that!the!domain!controller!is!set!
up.! If! it! still! wants! you! to! log! on! as! a! local! Administrator,! it’s! not! done,! yet.! Wait! for! it.!
!
If! you’re! watching,! you’ll! see! one! automatic! reboot! that! says! “DSC! is! restarting! your!
computer.”! After! that,! it! can! take! 20+! minutes! for! the! next! reboot,! and! for! everything! to!
finish.! Just! wait! for! it! –! stuff! is! happening! in! the! background.! Don’t! reArun! SetupLab.ps1!
anymore.!It!won’t!help,!and!might!hurt.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
8. After!Step!6!is!complete!and!you!can!log!on!to!the!server!as!LAB\Administrator,!repeat!Step!
6!on!the!Windows!8.1!virtual!machine.!If!you!did!log!on!to!the!server,!run!Logoff!to!log!off!of!
the!server.!
!
It’s!pretty!normal!to!see!a!lot!of!error!messages!when!running!our!SetupLab!script!on!the!
client.!Don’t!freak!out,!and!contact!us!if!you!have!questions!or!concerns.!When!you’re!done,!
you!should!be!able!to!log!on!as!LAB\Administrator.!
!
Optional!Steps!for!Your!Convenience!
You!may!want!to!configure!your!virtualization!software’s!shared!folders!feature!so!that!the!VM!can!
“see”!a!folder!on!your!host!computer.!That!folder!will!be!a!good!place!to!get!any!scripts!OUT!of!the!
VM!that!you!want!to!save!for!later.!
As!a!convenience,!log!on!to!the!client!computer!(LAB\Administrator,!Pa$$w0rd)!and!run!PowerShell!
(press!Windows+R,!type!powershell,!and!hit!Enter).!With!PowerShell!running,!rightAclick!its!
Taskbar!icon!to!pin!it!to!the!Taskbar.!That’ll!make!it!easier!to!get!to!in!the!future.!
At!this!point,!you!might!also!want!to!take!a!snapshot!of!the!virtual!machines!at!this!point.!They’re!in!a!
good,!“clean”!starting!condition!for!whatever!labs!you!might!want!to!perform.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
01 !
Discovering Commands
Background
Being!able!to!discover!commands!is!an!important!Windows!PowerShell!skill,!since!you!can’t!possibly!
memorize!the!thousands!of!commands!that!exist!in!the!base!operating!system.!Discovery!is!easier!in!
PowerShell!version!3!and!later,!thanks!to!module!autoAdiscovery!and!autoAloading.!
Syntax Review
Use!the!Get?Help!command!(or!Help,!if!you!want!automatic!pagination)!and!wildcards!(*)!to!search!
for!help!content!containing!a!specific!string!pattern:!
Help#*service*#
Stick!with!short,!singular!words!to!maximize!your!search!results.!Note!that!this!is!not!a!keyword%
search!like!Google;!it!is!a!simple!string!pattern!match.!You!cannot!provide!multiple!keywords.!
Remember!that!help!is!most!useful!after!you!have!run!Update?Help!at!least!once!to!download!and!
install!fresh!help!from!the!Internet.!Not!all!modules!will!include!help;!it!is!usual!to!see!error!messages!
after!updating.!
Use!the!Get?Command!command!and!wildcards!to!search!for!command!names.!
Get*Command#–Name#*proc*#
Get*Command#–Noun#*user*#
Get*Command#–Verb#Set#–Noun#*user*#
Exercises
Find!–*but*unless*noted,*do*not*run!–!commands!that!perform!the!following!tasks.!Notice!that!
italicized%words!are!meant!to!provide!you!a!clue,!but!remember!that!command!names!tend!to!use!
singular!nouns,!not!plural.!Write!your!answers!in!the!space!provided.!
1. Find!a!command!that!lists!the!network!adapters!installed!in!your!computer.!
!
!
!
2. Find!a!command!that!lets!you!write!to!an!event!log.!!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
3. Find!a!command!that!lists!the!history!of!PowerShell!commands!that!you!have!run!in!the!
current!session.!
!
!
!
4. Find!commands!that!will!stop!and!start!a!shell!transcript.%You!may!run!this!command!if!you!
want.!Notice!that!the!feature!is!not!supported!in!the!ISE.!
!
!
!
5. Find!commands!that!will!let!you!work!with!aliases!in!the!shell.!
!
!
!
6. Find!a!command!that!will!list!Windows!Firewall!rules.!
!
!
!
7. Find!a!command!that!will!list!inAuse!IP%addresses.!
!
!
!
8. Notice!that!some!of!the!commands!you!have!found!have!a!prefix!as!part!of!their!noun.!What!
prefix!is!used!for!commands!related!to!networking!and!the!Windows!Firewall?!
!
!
!
9. Find!and*run!a!command!that!will!list!all!legal!PowerShell!command!name!verbs.!
!
!
!
10. What!PowerShell!command!name!verb!is!used!for!commands!that!modify!some!existing!
component?!
!
!
!
11. What!PowerShell!command!name!verb!is!used!to!create!something!that!did!not!previously!
exist?!
!
!
!
12. Find!a!list!of!commands!that!work!with!CSVAformatted!data.!
!
!
!
13. Find!a!list!of!commands!that!work!with!XMLAformatted!data.!
!
!
!
14. Find!a!list!of!commands!that!work!with!generic!objects.!!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
15. The!help!system!also!provides!access!to!nonAcommandArelated!help!files.!Use!the!Help!
command!to!find!all!files!starting!with!the!word!about.!These!are!only!available!if!you!have!
updated!help.!
!
!
!
16. Can!you!find!a!nonAcommand!help!file,!or!files,!that!deal!with!functions?!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
02 !
Running Commands
Background
As!with!anything!used!to!give!instructions!to!computers,!PowerShell!is!very!picky!about!its!syntax.!
However,!PowerShell!also!offers!a!lot!of!flexibility!in!its!syntax,!which!means!commands!can!
sometimes!be!difficult!to!interpret!or!understand.!
Syntax Review
To!find!the!real!command!name!for!an!alias,!ask!for!Help!for!the!alias.!For!example:!
Help#dir#
Don’t!forget!to!read!the!–Full!or!–Detailed!help!for!a!command!to!learn!more!about!its!parameters.!!
!
!
!
Exercises
Answer!the!following!questions.!Unless!directed!otherwise,!you!do!not!need!to!run!any!commands.!
However,!you!may!want!to!look!at!the!help!for!specific!commands!to!learn!more!about!them!or!to!
remind!yourself!how!they!work.!
1. Can!you!specify!multiple!values!for!the!–Name!parameter!of!GetAService?!How!would!you!
write!a!command!that!retrieved!all!services!whose!names!started!with!S!and!with!W?!
!
!
!
2. If!you!run!Get?EventLog!and!use!the!–List!parameter,!can!you!also!use!the!–LogName!
parameter?!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
3. Without!running!it,!can!you!predict!what!the!following!command!will!do?!It’s!okay!to!read!
the!command’s!help.!What!parameter!is!the!value!s*!being!passed!to?!
PS#C:\>#ps#s*#
!
!
4. The!following!command!will!not!work.!Why?!How!could!you!fix!it!so!that!it!displays!a!list!of!
services!on!the!local!computer?!
PS#C:\>#gsv#localhost#
!
!
5. The!following!command!will!not!work.!Why?!How!could!you!fix!it!so!that!it!displays!a!list!of!
the!20!most!recent!events!from!the!Security!event!log!on!computer!DC1?!
PS#C:\>#get*eventlog#–security#20#–co#dc1#
!
!
6. Using!builtAin!aliases,!truncated!parameter!names,!and!positional!parameters,!rewrite!the!
following!command!to!use!as!few!characters!as!possible!while!accomplishing!the!same!
result:!
PS#C:\>#Get*WmiObject#–Class#Win32_BIOS#–Namespace#ROOT\Cimv2#
!
!
7. Assuming!computers.txt!contains!one!computer!name!per!line,!and!no!header!row,!will!the!
following!command!list!all!processes!running!on!the!computers!listed!in!computers.txt?!
PS#C:\>#Get*Process#–ComputerName#(Get*Content#computers.txt)#
!
!
8. Assuming!logs.txt!contains!one!event!log!name!per!line,!and!no!header!row,!will!the!
following!command!list!the!most!recent!20!events!from!each!event!log!listed!in!logs.txt?!Why!
or!why!not?!
PS#C:\>#Get*EventLog#–LogName#(Get*Content#logs.txt)#–Newest#20#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
03 !
Using PSProviders
Background
Remember!that!everything!in!a!PSDrive!looks%like!a!file!or!a!folder.!Generically,!these!are!referred!to!
as!items.%!
Some!items!can!have!contents!–!such!as!the!contents!of!a!file.!Other!items!do!not!have!content,!such!as!
a!folder.!Instead,!a!folder!has!child%items.%!
Some!items!can!have!item%properties,%such!as!the!readAonly!setting!of!a!file.!Usually,!you!can!get!and!
set!(read!and!write)!those!item!properties.!An!item!property!is!different!from!the!contents!of!an!item.!
For!example,!in!the!registry,!what!we!usually!refer!to!as!keys!are!items.%The!settings!of!the!key!are!
item%properties,%and!the!values!of!those!settings!are!item%property%values.%!
Syntax Review
Run!Get?Command*–Noun**Item*!to!see!a!list!of!commands!that!work!with!items!and!item!
properties.!!
Exercises
Write!down!the!commands!that!you!use!to!accomplish!each!task.!
1. Use!Windows!Notepad!to!create!a!text!file!in!C:\.!Then,!use!Windows!PowerShell!to!display!
the!item!properties!of!that!file.!
!
!
!
2. Use!Windows!PowerShell!to!change!the!text!file!to!readAonly.!To!do!this,!you!will!need!to!set!
an!item!property.!
!
!
!
3. In!the!HKCU:!drive,!change!to!the!
\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies!key.!Notice!the!Explorer!key.!
Display!its!item!properties.!Then,!display!any!child!items!it!has.!
!
!
!
!
!
4. The!Explorer!key!has!a!child!item,!Advanced.!It!has!a!setting,!DontPrettyPath.!Change!the!
value!of!that!setting!to!0.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
04 !
Connecting Commands
Background
Running!multiple!commands!in!the!pipeline!causes!the!output!of!each!command!to!be!passed,!or!
piped,%to!the!next!command.!After!the!last!command!runs,!PowerShell!will!attempt!to!display!
whatever!that!command!has!placed!into!the!pipeline.!
It!is!important!for!you!to!keep!track!of!what!is!in!the!pipeline!after!each!command,!because!that!
affects!what!the!next!command!will!have!to!work!with.!It!will!ultimately!also!affect!what!appears!on!
the!screen.!
Remember!that!parenthetical!commands!run!first,!and!their!output!replaces!the!parenthetical!
section.!Parentheticals!can!contain!their!own!subApipelines,!which!execute!entirely!before!the!main!
command!even!runs.!
Syntax Reminder
Remember!the!following!commands:!
• ImportACSV,!ConvertToACSV,!and!ExportACSV!
• ImportACliXML!and!ExportACliXML!
• GetAContent!
• ConvertToAHTML!
• OutAFile!
Exercises
Complete!the!following!tasks.!Write!down!your!answers!for!future!reference.!
1. Create!a!CSV!file!named!Services.csv!that!contains!all!of!the!services!running!on!the!local!
computer.!Then,!use!Notepad!to!open!the!CSV!file.!What!is!the!significance!of!the!items!listed!
inside!{curly!brackets}?!
!
!
!
!
2. Use!Get?Content!to!read!the!CSV!file!that!you!created!in!Step!1.!Is!PowerShell!doing!anything!
with!the!data!before!displaying!it?!
!
!
!
3. Use!Import?CSV!to!read!the!CSV!file!that!you!created!in!Step!1.!How!is!this!command!
different!from!GetAContent?!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
4. Run!the!following!command,!and!explain!what!appears!on!the!screen,!and!why:!
PS#C:\>#Get*Process#|#Export*CSV#processes.csv#
!
!
!
5. Run!the!following!command,!and!explain!what!appears!in!Output.txt,!and!why:!
PS#C:\>#Get*Process#|#Export*CSV#processes.csv#|#Out*File#Output.txt#
!
!
!
6. How!are!the!following!three!command!lines!different?!Do!they!produce!the!same!result?!You!
can!run!them!to!test!them.!
PS#C:\>#Get*Service#|#Export*CSV#serv.csv#
PS#C:\>#Get*Service#|#ConvertTo*CSV##
PS#C:\>#Get*Service#|#ConvertTo*CSV#|#Out*File#serv.csv#
!
!
!
!
7. Produce!an!HTML!file!named!Security.html!that!contains!the!50!most!recent!events!from!the!
local!Security!event!log.!
!
!
!
8. The!ConvertTo?HTML!command!has!two!parameter!sets.!One,!used!with!the!–Fragment!
switch,!produces!an!HTML!fragment.!How!is!an!HTML!fragment!different!from!what!the!
command!produces!when!run!without!the!–Fragment!switch?!
!
!
!
!
9. What!is!the!difference!between!these!two!command!lines?!
PS#C:\>#Get*Service#|#Out*File#serv.txt#
PS#C:\>#Get*Service#|#ConvertTo*CSV#|#Out*File#serv.txt#
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
10. Run!Windows!Notepad.!Then,!run!a!PowerShell!command!that!will!terminate!all!instances!of!
Windows!Notepad.!
!
!
11. When!running!Export?CliXML,!how!could!you!tell!the!command!to!not!overwrite!any!
existing!files?!
!
!
!
12. How!could!you!tell!Export?CSV!to!create!a!file!that!is!delimited!with!a!pipe!character,!instead!
of!a!comma?!Is!it!possible!to!read!that!same!file!by!using!Import?CSV?!
!
!
!
13. How!could!you!remove!the!“#”!comment!line!from!the!top!of!the!files!created!by!Export?
CSV?!
!
!
!
14. Write!two!different!commands!that!would!stop!a!service!named!BITS.!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
05 !
Extending the Shell
Exercises
*
Exercise*1*
Windows!7!and!later!includes!a!module!named!TroubleshootingPack.!The!module!contains!two!
commands!that!are!used!to!retrieve!and!run!troubleshooting!packs.!The!actual!troubleshooting!packs!
are!installed!in!C:\Windows\Diagnostics\System!–!you!can!get!a!directory!of!that!location!to!see!the!
available!packs.!
Your!task!is!to!run!the!Networking!pack.!Doing!so!will!require!you!to!run!two!commands!in!a!single!
pipeline.!If!you!successfully!run!the!pack,!you!will!be!prompted!for!an!ID;!just!press!Enter!to!continue!
to!the!pack’s!menu.!Run!a!connectivity!test,!and!then!exit!the!pack,!by!using!the!menu.!
Exercise*2!
This!exercise!requires!Windows!8!or!later,!or!Windows!Server!2012!or!later.!
Using!Windows!PowerShell,!create!a!new!SMB%share!(shared!folder).!The!share!must!be!named!
Windows,!and!it!should!point!to!the!C:\Windows!path!on!your!local!computer.!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
06 !
Working with Objects
Background
Understanding!that!PowerShell!commands!produce!objects,!and!not!text,!is!crucial!to!using!the!shell!
to!its!fullest.!Objects!are!placed!into!the!pipeline,!and!they!can!be!examined!and!manipulated!by!each!
command!in!the!pipeline.!Whatever!objects!are!in!the!pipeline!after!the!last!command!runs,!are!
converted!to!text!for!display.!
Syntax Review
Commands!to!remember:!
• GetAMember!(gm)!
• SortAObject!(sort)!
• SelectAObject!(select),!and!especially!Select**!
• MeasureAObject!
To!create!a!custom!property!using!SelectAObject,!the!syntax!is!something!like!this:!
Get*Process#|##
Select*Object#–Properties#Name,Id,@{n='VM';e={$_.VM#/#1MB}}#
The!@{}!construct!is!called!a!hash%table,%and!it!consists!of!key=value!pairs.%The!SelectAObject!
command!expects!two!keys.!The!first!key!can!be!name,!label,!n,!or!l!(lowercase!“L”).!The!value!for!
the!first!key!is!the!name!of!your!custom!property.!A!semicolon!separates!the!first!pair!from!the!
second!pair.!The!second!key!can!be!e!or!expression,!and!its!value!is!a!script!block!that!calculates!the!
custom!property!value.!Inside!that!script!block,!you!can!use!$_!or!$PSItem!(in!v3+)!to!refer!to!the!
object!that!was!piped!into!SelectAObject.!
Each!custom!property!is!considered!a!single!property!entry!in!the!commaAseparated!list!of!properties!
that!you!want!SelectAObject!to!output.!
Remember!that!SelectAObject!can!define!a!property!list,!and!that!it!can!also!select!an!arbitrary!
number!of!–First!or!–Last!objects!to!keep.!You!will!often!sort!the!objects!into!a!particular!order!
before!selecting!them.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Write!down!your!answers!to!the!following!tasks.!
1. Display!a!list!of!the!5!processes!using!the!most!virtual!memory!(VM).!Have!the!display!
include!the!usual!number!of!columns.!
!
!
!
2. What!does!the!following!command!produce?!Why?!
Get*Process#|#Select#–Property#Name,ID,Virtual,Physical,CPU#
!
!
3. What!does!the!following!command!produce?!Is!the!output!sorted!as!desired?!Why?!
Get*Service#|#Select#Name,DisplayName#|#Sort#Status#
!
!
4. Find!a!command!that!produces!the!current!date!and!time.!
!
!
!
5. Display!only!the!current!day!of!the!week!(e.g.,!Monday!or!Tuesday).!Note!that!the!output!may!
be!rightAaligned!–!if!you!seem!to!be!getting!several!blank!lines!of!output,!make!sure!you!are!
scrolling!to!the!right.!
!
!
!
6. Run!the!command!from!task!4!again,!and!find!the!type%name!for!this!kind!of!object.!You!can!
use!GetAMember!to!do!this.!
!
!
!
7. Display!the!50!most!recent!entries!from!the!Security!event!log.!Display!the!time!written,!the!
index,!and!the!source!for!each!entry.!!
!
!
!
!
!
!
!
!
Continued!on!the!next!page…!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
8. Display!the!most!recent!commands!in!the!PowerShell!command!history.!Your!output!should!
include!the!ID!number,!the!command!text,!and!the!amount!of!time!it!took!the!command!to!
run.!Include!only!the!10!longestArunning!commands,!and!sort!them!so!that!the!longestA
running!command!is!first.!!
!
You!will!have!to!create!a!custom!property!that!includes!the!elapsed!time.!You!will!then!select!
and!sort!on!that!property.!To!make!things!easier,!your!custom!property!name!should!not!
contain!spaces!or!special!characters.!“ElapsedTime”!would!make!a!good!custom!property!
name.!
!
You!do!not!need!to!generate!TimeSpan!or!other!special!objects!to!complete!this!task.!If!you!
have!the!time!a!command!started!and!the!time!it!ended,!you!should!be!able!to!subtract!one!
from!the!other!to!find!the!time!elapsed.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
07 !
Understanding the Pipeline
Background
Remember!that!PowerShell!always!tries!to!bind!pipeline!input!ByValue!first.!That!means!it!looks!at!
the!type%of!object!in!the!pipeline,!and!tries!to!find!a!parameter!that!can!accept!that!same%type!from!the!
pipeline,!ByValue.!
The![object]!type!is!generic.!A!parameter!that!accepts![object]!will!accept!anything.!
If!that!fails,!the!shell!will!try!ByPropertyName.!In!this!mode,!it!will!match!properties!on!the!pipeline!
object!to!parameters!of!the!command!based%on%how%they%are%spelled.%So!a!“Fred”!property!would!
match!to!a!–Fred!parameter.!Parameters!must!be!coded!to!accept!pipeline!input!ByPropertyName.!
Syntax Review
Remember!that!you!can!pipe!objects!to!Get?Member!to!see!their!type!name,!and!a!list!of!their!
properties.!
Exercises
In!these!exercises!do*not*run*the*commands*to*see*if*they*work.*Your!task!is!to!figure!out!if!you!
think!they!would!work!or!not.!You!may!read!the!help!files!for!any!of!these!commands!to!learn!more!
about!their!parameters.!You!may!run!underlined!commands!and!pipe!their!output!to!Get?Member,!if!
needed.!
For!your!information,!Get?ADComputer*–filter**!will!retrieve!all!computer!objects!form!the!domain.!
These!objects!have!a!Name!property,!which!contains!the!computers’!names.!You!do!not!need!to!run!
GetAADComputer,!nor!do!you!need!to!read!the!help!for!GetAADComputer.!You!now!know!everything!
you!need!to!know!about!that!command.!
Some!exercises!refer!to!Computers.txt.!You!can!assume!that!this!text!file!contains!one!computer!
name!per!line,!with!no!header!row.!
Some!exercises!refer!to!Computers.csv.!You!can!assume!that!this!CSV!file!contains!one!computer!
name!per!line,!and!has!a!header!row!containing!“ComputerName”!as!its!only!column.!
!
!
!
!
!
Your!tasks!begin!on!the!next!page.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
1. Will!the!following!command!work!to!display!a!list!of!services!running!on!all!computers!in!the!
domain?!Why!or!why!not?!
Get*ADComputer#–Filter#*#|#Get*Service#–Name#*#
!
!
2. Will!the!following!command!work!to!display!a!list!of!services!running!on!all!computers!in!the!
domain?!Why!or!why!not?!
Get*ADComputer#–Filter#*#|#
Select*Object#–Properties#@{n='ComputerName';e={$_.Name}}#|#
Get*Service#–Name#*#
!
!
3. Will!the!following!command!work!to!display!the!indicated!WMI!class!from!all!computers!in!
the!domain?!Why!or!why!not?!
Get*ADComputer#–Filter#*#|#
Select*Object#–Properties#@{n='ComputerName';e={$_.Name}}#|#
Get*WmiObject#–Class#Win32_BIOS#
!
!
4. Will!the!following!command!work!to!display!the!indicated!WMI!class!from!all!computers!in!
Computers.txt?!Why!or!why!not?!
Get*WmiObject#–Class#Win32_BIOS#–ComputerName#(Get*Content#Computers.txt)#
!
!
5. Will!the!following!command!work!to!display!a!list!of!all!processes!from!all!computers!in!the!
domain?!Why!or!why!not?!
Get*Process#–Name#*#*ComputerName#(Get*ADComputer#–Filter#*#|#
###################################Select*Object#–Expand#Name)#
!
!
6. Will!the!following!command!work!to!display!a!list!of!all!Security!event!log!entries!from!all!
computers!in!Computers.csv?!Why!or!why!not?!
Import*CSV#Computers.CSV#|#Get*EventLog#–LogName#Security#
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
08 !
Formatting
Background
Remember!that!formatting!commands!produce!a!special!kind!of!object!that!can!only!be!consumed!by!
OutAHost,!OutAFile,!OutAPrinter,!and!OutAString.!OutAHost!is!actually!the!default,!which!is!why!
command!output!shows!up!on!the!screen!by!default.!Any!of!the!other!OutA!commands!will!produce!
the!same%looking%output!as!the!screen!would!–!they!just!put!the!output!in!a!different!place.!
Syntax Review
Commands!to!remember:!
• FormatATable!(ft)!
o –GroupBy,!AWrap,!and!–AutoSize!!
• FormatAList!(fl)!
• FormatAWide!(fw)!
The!custom!column!syntax!can!be!used!by!these!commands,!as!part!of!a!property!list.!However,!keep!
in!mind!that!you!are!not!producing!custom!columns,!like!you!would!with!SelectAObject.!Format!
commands!produce!data!designed!only!for!display.!Because!they!are!designed!for!display,!these!
custom!columns!can!include!additional!keys.!
• Name,!Label,!N,!or!L!–!same!as!used!with!SelectAObject,!defines!the!custom!heading!
• Expression!or!E!–!same!as!used!with!SelectAObject;!a!script!block!that!defines!the!contents!–!
use!$_!or!$PSItem!(v3+)!to!refer!to!the!object!you’re!formatting!
• Width!–!numeric!value!indicating!maximum!width!of!the!column!(won’t!truncate!the!header)!
• Align!–!“right”!or!“left”!
• FormatString!–!a!.NET!Framework!formatting!string;!for!example,!“N2”!is!a!number!with!2!
decimal!places!
Get*Process#|#Format*Table#–properties#Name,ID,@{n='VM(MB)';e={$_.VM#/#
1MB};formatstring="N2"},@{n='PM(MB)';e={$_.PM#/#1MB};formatstring="N2"}#
–AutoSize#
A!custom!column!hash!table!in!a!more!legible!format!looks!like!this:!
@{name="Column";#
##expression={#$_.Property#};#
##formatString="N2";#
##width=2;#
##align="left"}#
Your!exercises!begin!on!the!next!page.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Write!down!your!answers!to!the!following!tasks:!
1. Display!a!table!of!services.!Include!the!name,!display!name,!and!status.!List!running!services!
first,!then!stopped!services.!Have!a!new!set!of!table!headers!generated!for!stopped!services.!
!
!
!
2. Display!a!table!of!processes,!including!only!the!name!and!ID.!Have!table!take!up!as!little!
horizontal!room!as!possible.!
!
!
!
3. Use!the!following!command!as!starting!point.!Have!the!final!result!be!a!table!including!the!
DeviceID,!FreeSpace,!and!Size.!Have!FreeSpace!and!Size!expressed!in!gigabytes.!
Get*WmiObject#–Class#Win32_LogicalDisk#–Filter#"DriveType=3"#
!
!
4. Use!the!following!command!as!a!starting!point.!Have!the!final!result!be!a!table!that!lists!the!
log!name,!and!retention!period.!The!column!names!must!be!“LogName”!and!“RetDays.”!
Retention!days!must!be!rightAaligned.!
Get*EventLog#–List#
!
!
5. Display!a!list!of!all!files!(and!only!files)!in!the!C:\Windows!directory.!Include!only!files!larger!
than!100MB,!and!format!the!output!to!show!the!filename!and!file!size.!Express!the!file!size!in!
MB.!Make!sure!the!resulting!table!does!not!waste!horizontal!space.!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
09 !
Filtering and Comparisons
Background
Remember!that!filtering!should!be!done!as!early!in!the!commandAline!as!possible.!That!means!
reviewing!each!command!to!determine!its!filtering!capabilities.!Where?Object!is!not!always!the!
correct!answer.!
Also!remember!that!commands!having!a!–Filter!parameter!usually!do!not!process!the!filter!
themselves.!Instead,!the!pass!the!filter!criteria!you!provide!down!to!the!underlying!technology.!That!
means!these!filters!do!not!always!use!PowerShell!comparison!filter!syntax.!You!may!need!to!read!the!
command’s!help!to!find!the!correct!syntax.!
Syntax Review
Comparison!operators!include:!
• Aeq,!Ane,!Agt,!Age,!Alt,!Ale!
• Use!–ceq!and!–cne!for!caseAsensitive!string!comparisons!
• Use!–like!to!perform!simple!wildcard!comparisons!(*!and!?!are!wildcards)!
• Do!not!use!–contains,!as!it!is!NOT!a!pattern!match!or!wildcard!comparison!
• Use!–match!for!regular!expression!comparisons!–!not!covered!here!
• Use!–and!and!–or!for!Boolean!comparisons;!group!subAcomparisons!using!(parentheses)!
The!“simple”!syntax!for!WhereAObject!can!handle!only!a!single!comparison!and!takes!the!form:!
Where*Object#<property>#<operator>#<value>#
As!in:!
Get*Service#|#Where#Status#–eq#"Running"#
The!“complete”!syntax!uses!a!script!block.!Within!that!script!block,!use!$_!(or!$PSItem!in!v3+)!to!refer!
to!the!pipedAin!object.!For!example:!
Get*WmiObject#–Class#Win32_Service#|#
Where#{#$_.State#–eq#"Running"#–and#$_.Name#–like#"s*"#
!
!
Your!tasks!begin!on!the!next!page.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Write!down!your!solutions!to!these!tasks:!
1. Using!the!Get?NetAdapter!command,!display!a!list!of!only!physical!network!adapters.!
!
!
!
2. Using!the!Get?DNSClientCache!command,!display!a!list!of!cached!“A”!type!records.!If!there!
are!none,!try!pinging!a!computer!by!name!to!add!records!to!the!cache,!and!then!try!again.!
!
!
!
3. Using!the!Get?PSDrive!command,!display!a!list!of!drives!that!use!the!FileSystem!PSProvider.!
!
!
!
4. Display!a!list!of!processes!running!as!either!Conhost!or!Svchost.!
!
!
!
5. Display!a!list!of!installed!hotfixes!that!were!installed!by!the!Administrator!account.!If!your!
computer!does!not!contain!any!hotfixes,!you!can!skip!this!item.!But,!seriously,!run!Windows!
Update!sometime.!
!
!
!
6. Use!the!following!command!as!a!starting!point.!Display!a!list!of!drives!whose!free!space!is!
less!than!99%!of!the!disk!capacity!(we!use!99%!because,!here!in!class,!you!aren’t!likely!to!
have!drives!that!are!low!on!free!space).!In!the!final!output,!include!columns!for!the!drive!
letter,!the!free!space,!the!drive!size,!and!the!free!percentage.!Express!the!percentage!as!a!
whole!number,!but!do!not!include!a!percent!sign!(%)!in!the!row.!
!
!
!
7. Display!a!list!of!Windows!Firewall!rules!that!are!enabled.!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
10 !
Enumerating Objects
Background
Whenever!you!have!a!command!that!produces!multiple!objects,!you!have!to!do!one!of!two!things:!
• Pipe!the!command’s!output!to!another!command!that!can!accept!those!objects!as!input!via!
the!pipeline!
• Enumerate!the!objects!by!using!ForEachAObject.!In!the!script!block!of!ForEachAObject,!use!$_!
(or!$PSItem!in!v3+)!to!work!with!the!objects!on!at!a!time.!
Syntax Review
The!ForEachAObject!command!uses!a!script!block.!For!example,!to!execute!the!imaginary!Kneel()!
method!of!a!fictional!Person!object,!you!might!run!this:!
Get*Person#|#ForEach*Object#{#$_.Kneel()#}#
Remember!that!method!names!are!always!followed!immediately!by!().!Methods!that!require!input!
arguments!have!those!listed!in!a!commaAseparated!list!within!the!parentheses.!
Exercises
Write!down!your!answers!to!the!following:!
1. You!can!use!the!following!command!to!query!all!instances!of!the!BITS!service!by!using!WMI.!
Each!instance!produced!by!this!command!has!a!Change()!method.!Do!change!the!password!
of!the!service,!you!would!run!
Change($null,$null,$null,$null,$null,$null,$null,"P@ssw0rd").!The!result!will!be!an!
object!having!a!ReturnValue!property!of!0,!if!the!change!was!successful.!Using!the!following!
command!as!a!starting!point,!change!the!services’!passwords!to!Pa$$w0rd.!
Get*WmiObject#–Class#Win32_Service#–Filter#"name='bits'"#
!
!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
2. Run!the!following!commands!and!observe!their!output.!Using!that!output!and!what!you!
already!know,!write!at!least!four!commands!that!could!terminate!all!running!instances!of!
Notepad.!You!can!test!these!commands!–!run!multiple!copies!of!Notepad!before!each!test.!
PS#C:\>#Get*Service#|#GM#
PS#C:\>#Get*WmiObject#–Class#Win32_Process#|#GM#
!
!
!
!
!
3. Write!at!least!two!commands!(do!not!try!and!run!them)!that!would!pause!all!running!
services.!!
!
!
4. The!following!command!will!retrieve!instances!of!the!WMI!Win32_OperatingSystem!class!
from!multiple!computers.!Each!instance!has!a!Win32Shutdown()!method.!That!method!
accepts!a!numeric!argument.!For!example,!0!will!cause!the!computers!to!log!off!any!loggedA
on!user.!Write,!but!do*not*run,!a!complete!command!that!will!log!off!the!loggedAon!user!on!
all!queried!computers.!
Get*WmiObject#–Class#Win32_OperatingSystem#–ComputerName#DC1,SRV2,DC2#
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
11 !
Variables
PS#C:\>#$Var#=#"x"#
PS#C:\>#New*Variable#–Name#$Var#–Value#7#
That!creates!a!new!variable,!$x,!containing!the!value!7.!Keep!looking!at!the!example!until!you’re!sure!
you!understand!why.!
In!double!quotation!marks,!PowerShell!replaces!variables!with!their!contents:!
PS#C:\>#$msg#=#"Student"#
PS#C:\>#$text#=#"Hello,#$msg"#
PS#C:\>#$text#
Hello,#Student#
However,!this!only!works!with!variables!–!you!cannot!use!this!same!technique!to!access!properties,!
array!indices,!etc.!To!do!those,!you!must!use!a!subexpression:!
PS#C:\>#$services#=#Get*Service#
PS#C:\>#$message#=#"The#name#of#the#first#service#is#$($services[0].name)"#
PS#C:\>#$message#
The#name#of#the#first#service#is#AeLookupSvc#
Using!these!techniques!is!a!better!practice!than!concatenating!strings!and!variables.! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Remember!that!you!can!declare!a!type!for!your!variables.!Common!types!include![string],![int],!
[bool],![xml],![datetime],!and!others.!
PS#C:\>#[int]$x#=#5#
PS#C:\>#$x#=#"Hello"#
Cannot#convert#value#"Hello"#to#type#"System.Int32".#Error:#"Input#
string#was#not#in#a#correct#format."#
At#line:1#char:1#
+#$x#=#"Hello"#
+#~~~~~~~~~~~~#
####+#CategoryInfo##########:#MetadataError:#(:)#[],#
ArgumentTransformationMetadataException#
####+#FullyQualifiedErrorId#:#RuntimeException#
#
PS#C:\>#[string]$x#=#"Hello"#
PS#C:\>#$x#
Hello#
Exercises
Write!down!your!answers!for!the!following!tasks:!
1. Display!a!list!of!all!currently!defined!variables.!
!
!
!
2. Create!a!variable!named!x!and!populate!it!with!the!number!100.!
!
!
!
3. Completely!remove!the!variable!named!x.!
!
!
!
4. Place!all!running!processes!into!a!new!variable!named!procs.!
!
!
!
5. Display!the!first!object!in!$procs.!
!
!
!
6. Display!the!name!of!the!first!object!in!$procs.!
!
!
!
7. Create!a!message,!“The!first!proc!name!is!___”.!Store!the!message!in!$message,!and!insert!the!
name!of!the!first!object!in!$procs!in!place!of!the!___.!!
!
!
!
8. Use!the!–replace!operator!to!replace!“proc”!with!“process”!in!$message.!Read!
about_comparison_operators!for!more!information!on!the!–replace!operator.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
9. Use!the!–split!operator!to!split!the!string!“one,two,three”!into!an!array!of!three!items.!Store!
the!array!in!$arr,!and!then!display!the!second!item!in!the!array.!Read!about_split!for!
information!on!the!operator.!
!
!
!
10. Using![datetime],!create!a!variable!named!$then!that!contains!the!DateTime!value!for!the!
string!“11/22/1971”.!Pipe!$then!to!GetAMember!to!verify!that!it!is!the!correct!type.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
12 !
Remoting and PSSessions
$! Windows 8+ !
Background
Remember!that!incoming!remoting!sessions!are!only!enabled!by!default!on!Windows!Server!2012!
R2.!For!other!operating!systems,!you!must!run!Enable?PSRemoting!to!enable!incoming!connections.!
Syntax Review
Remember!the!following!commands:!
• Invoke?Command!can!send!a!command,!or!the!contents!of!a!script!file,!to!one!or!more!
remote!computers.!You!can!specify!computer!names!for!adAhoc!sessions,!or!specify!
PSSession!objects!to!use!a!persistent!session.!
• Enter?PSSession!lets!you!interact!with!a!single!remote!computer.!You!can!specify!a!
computer!name!for!an!adAhoc!session,!or!a!single!PSSession!object!to!use!that!persistent!
session.!
• New?PSSession!creates!a!new!persistent!session!on!a!remote!computer.!The!resulting!
session!object!is!often!stored!in!a!variable!for!easier!access.!
• Import?Module!can!be!used!to!import!commands!from!a!remote!module.!You!must!specify!
an!existing!PSSession!object!to!import!from.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
• Enable?PSRemoting!can!enable!remoting!on!the!local!computer.!Add!!
–SkipNetworkProfileCheck!if!your!computer!includes!network!interfaces!marked!as!
“public.”!This!is!often!the!case!on!computers!where!a!workstation!virtualization!product!is!
installed.!
Exercises
1. Start!by!enabling!remoting,!if!it!is!not!already!enabled,!on!all!of!your!virtual!machines.!If!you!
only!have!one!virtual!machine,!or!are!using!your!host!computer,!enable!remoting!on!it.!
!
For!the!following!exercises,!provide!a!commaAseparated!list!of!your!computer!and/or!virtual!
machine!names.!Use!localhost!to!access!your!local!computer!via!remoting.!
!
2. Using!Invoke?Command,!send!the!following!command!to!one!or!more!computers:!
Get*EventLog#–LogName#Security#–Newest#100#
!
!
3. Use!New?PSSession!to!create!a!session!to!a!single!remote!computer.!Save!the!session!object!
in!the!variable!$remote.!!
!
!
4. Use!Get?Module,!passing!it!the!session!in!$remote,!to!list!the!available!modules!on!the!
remote!computer.!You!may!need!to!read!the!help!on!GetAModule!to!find!the!correct!
parameters!for!this.!
!
!
!
5. Use!Import?Module,!passing!in!the!session!in!$remote,!to!import!the!NetAdapter!module!
from!the!remote!computer.!Prefix!the!imported!commands!with!“Remote”.!You!may!need!to!
read!the!help!on!ImportAModule!to!find!the!correct!parameters!for!this.!
!
!
!
6. Run!the!GetANetAdapter!command!from!the!remote!computer.!The!command!name!should!
be!Get?RemoteNetAdapter!if!you!completed!the!previous!tasks!correctly.!
!
!
!
7. Use!Get?PSSession!and!Remove?PSSession!to!close!all!open!PSSessions!on!your!computer.!
After!doing!so,!try!running!GetARemoteNetAdapter!again.!What!happens?!Why?!
!
!
!
8. Use!Enter?PSSession!and!a!computer!name!to!interactively!remote!to!a!single!computer!(it!
can!be!localhost).!Notice!the!change!in!the!PowerShell!prompt.!Try!to!run!EnterAPSSession!
again.!What!happens?!Why?!Run!Exit!to!close!the!session.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
13 !
WMI and CIM
Background
WMI!and!CIM!provide!two!different!ways!of!accessing!the!same!Management!Repository.!WMI!
communicates!with!the!Windows!Management!Instrumentation!service!over!RPC/DCOM;!CIM!
communicates!by!using!WSAMAN!(Windows!Remote!Management,!or!WinRM).!!
!
CIM!commands!that!accept!a!–ComputerName!can!create!and!use!an!adAhoc!CimSession.!You!can!also!
manually!create!CimSession!objects,!and!reAuse!those!CimSessions!for!multiple!commands.!
CimSessions!use!WSAMAN!by!default,!but!you!can!specify!a!CimSessionOption!that!causes!the!session!
to!use!DCOM!instead.!DCOM!is!useful!for!backward!compatibility.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Organization!
WMI!is!organized!into!a!set!of!namespaces.%The!default,!root\CIMv2,!is!used!when!you!do!not!specify!
a!namespace.!Root\CIMv2!contains!many!of!the!WMI!elements!related!to!the!core!OS!and!computer!
hardware.!Many!of!those!elements!are!prefixed!with!Win32_;!that!isn’t!the!case!elsewhere.!
Namespaces!contain!classes,!which!are!abstract!descriptions!of!a!managed!element.!A!given!computer!
may!contain!zero!or!more!instances!of!each!class.!An!instance!is!a!realAworld!occurrence!of!a!class.!!
!
Learn!More!
You’ll!find!more!information!in!PowerShell%In%Depth!and!PowerShell%and%WMI,!both!available!from!
major!booksellers.!
Syntax Review
WMI!Commands!
• Get?WmiObject!can!retrieve!instances!of!a!specified!class.!You!can!specify!a!namespace,!if!it!
isn’t!the!default!ROOT\CIMv2.!You!can!specify!a!filter,!using!WMI!filter!syntax.!WMI!objects!
have!properties!and!methods.!
!
• Get?WmiObject!can!also!list!the!classes!in!a!specified!namespace.!
!
• Invoke?WmiMethod!can!run!a!specified!method!of!a!WMI!instance.!You!often!get!the!
instance,!and!then!pipe!it!to!InvokeAWmiMethod.!The!method!argument!list!is!a!commaA
separated!list!of!values,!that!must!be!in!the!correct!order.!$null!values!are!not!allowed.!
!
CIM!Commands!
CIM!makes!it!easier!to!deal!with!classes!and!instances!separately.!Don’t!confuse!the!two.!
• A!class!is!an!abstract!description!of!a!management!object.!It!describes!the!properties!an!
object!has,!and!the!methods!it!can!run.!A!class!does!not!contain!actual,!current!management!
information.!
!
• An!instance!is!a!concrete,!realAworld!occurrence!of!a!class.!Its!properties!contain!actual!
values.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
To!list!the!classes!in!a!namespace:!
PS#C:\>#Get*CimClass#–Namespace#ROOT\CIMv2#
!
To!list!the!properties!of!a!class:!
PS#C:\>#Get*CimClass#–ClassName#Win32_BIOS#|##
Select#–Expand#CimClassProperties#
To!list!the!methods!of!a!class:!
PS#C:\>#Get*CimClass#–ClassName#Win32_OperatingSystem#|#
Select#–Expand#CimClassMethods#
To!query!the!instances!of!a!class,!using!a!filter:!
PS#C:\>#Get*CimInstance#–ClassName#Win32_LogicalDisk##
########################–Filter#"DriveType=3"#|#
Select#–Properties#*#
To!run!a!method!of!a!class:!
PS#C:\>#Get*CimInstance#–ClassName#Win32_Service##
########################–Filter#"Name='BITS'"#|#
Invoke*CimMethod#–Method#Change#
#################*Argument#@{'StartPassword'='P@ssw0rd'}#
Notice!that!the!argument!is!a!hash!table,!where!the!keys!are!the!argument!names!and!the!values!are!
the!argument!values.!You!will!usually!need!to!use!an!Internet!search!for!the!class!documentation!to!
find!the!appropriate!names.!You!can!also!discover!the!arguments!like!this:!
PS#C:\>#Get*CimClass#–ClassName#Win32_Service#|#
Select#–Expand#CimClassMethods#|#
Where#Name#–eq#'Change'#|#
Select#–Expand#Parameters#
That!example!shows!the!arguments!for!the!Change()!method!of!Win32_Service.!
To!create!a!new!CimSession!that!uses!WinRM:!
PS#C:\>#$example#=#New*CimSession#–ComputerName#DC1#
To!create!a!new!CimSession!that!uses!DCOM:!
PS#C:\>#$example#=#New*CimSession#–ComputerName#XPCLIENT#
########*SessionOption#(New*CimSessionOption#–Protocol#DCOM)#
Either!session!can!then!be!used!to!query!classes!and!instances:!
PS#C:\>#Get*CimInstance#–ClassName#Win32_ComputerSystem#
########################*CimSession#$example#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Write!down!your!answers!to!the!following!tasks.!Unless!directed!otherwise,!try!to!use!the!newer!CIM!
commands!to!complete!each!task.!Remember!to!use!–Filter!when!appropriate.!If!you!have!more!than!
one!computer,!practice!retrieving!information!from!one!or!more!computers!at!the!same!time.!
!
1. Display!all!instances,!and!all!properties,!of!the!Win32_OperatingSystem!class.!
!
!
!
2. Using!the!Win32_OperatingSystem!class,!create!a!commandAline!that!will!display!output!as!
close!to!the!following!as!possible!(noting!that!property!values!may!be!different!on!your!
computer(s)):!
BuildNumber#Version##SPVersion#OSArchitecture#
***********#*******##*********#**************#
9200########6.2.9200#########0#64*bit#
!
!
3. Using!the!Win32_Service!class,!display!a!list!of!services!that!are!set!to!start!automatically,!but!
that!are!not!currently!running.!
!
!
!
4. Using!the!Win32_NetworkAdapterConfiguration!class,!display!a!list!of!configurations!where!
DHCP!is!enabled.!Display!only!the!interface!index!and!description!of!each.!
!
!
!
5. Use!both!GetAWmiObject!and!GetACimInstance!to!retrieve!the!Win32_ComputerSystem!class.!
Can!you!see!any!differences!in!the!information!these!two!commands!return?!
!
!
!
6. Display!all!instances!of!the!Win32_UserAccount!class.!Is!this!local!or!domain!users?!(On!a!
nonAdomain!computer,!you!will!not!be!able!to!tell!the!difference.)!
!
!
!
7. Create!a!CimSession!to!a!computer,!using!the!default!WSAMAN!protocol.!Save!the!session!in!a!
variable.!Then,!use!the!variable!to!query!all!instances!of!the!Win32_Process!class.!
!
!
!
8. Create!a!CimSession!to!a!computer,!using!the!DCOM!protocol.!Save!that!session!in!a!variable.!
Then,!use!that!variable!to!query!all!instances!of!the!Win32_BIOS!class.!
!
!
!
9. Close!all!open!CimSessions.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
10. Display!a!list!of!all!classes!whose!names!contain!“Network.”!Notice!that!GetACimClass!does!
not!use!a!–Filter!parameter;!you!might!need!to!use!WhereAObject!to!perform!the!filtering.!
!
!
!
11. Using!only!GetACimClass,!display!a!list!of!all!classes!in!the!default!namespace!that!have!a!
Change!method.!
!
!
!
12. Query!all!instances!of!the!Win32_Processor!class.!Do!the!results!show!you!the!number!of!
cores!each!socket!contains?!How!can!you!tell!if!it!is!a!32Abit!or!64Abit!processor?!
!
!
!
13. !Is!it!possible!to!use!only%GetACimClass!to!display!a!list!of!all!classes!whose!names!contain!
“session”?!
!
!
!
14. Using!Win32_OperatingSystem,!display!computers’!last!boot!up!time.!Notice!how!the!values!
are!different!when!you!use!CIM!or!WMI!to!display!this!information.!Which!do!you!prefer?!
!
!
!
15. Using!Win32_Service,!display!a!list!of!all!services!that!do!not!log!on!using!a!builtAin!account!
like!LocalSystem,!Local!Service,!or!Network!Service.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
14 !
Discovering Commands
Background
Windows!PowerShell!2!introduced!three!kinds!of!jobs;!v3!introduced!a!fourth.!Background!jobs!run!
as!part!of!a!PowerShell!session;!if!you!close!the!session,!the!jobs!are!gone.!The!only!native!exception!
is!the!new!scheduled!job!in!v3.!That!exists!in!the!Windows!Task!Scheduler,!and!it!will!persist!across!
shell!sessions.!
Most!jobs!consist!of!a!parent%job,!and!then!one!or!more!child%jobs.%The!child!jobs!each!engage!with!one!
computer.!For!local!jobs,!there!is!only!ever!one!child!job,!but!there!is!always!a!parent!job.!
Syntax Review
To!start!different!kinds!of!jobs:!
• Start?Job!can!run!any!local!command!in!the!background!
• Invoke?Command!can!send!commands!or!files!to!remote!computers!via!remoting;!using!!
–AsJob!makes!it!run!those!in!the!background!
• Get?WmiObject!also!has!an!–AsJob!parameter;!the!CIM!commands!do!not!have!an!–AsJob!
parameter.!You!can!achieve!the!same!effect!by!simply!using!them!with!InvokeACommand.!
• The!PSScheduledJob*contains!command!used!to!create!and!manage!scheduled!jobs!
To!work!with!jobs:!
• Get?Job!retrieves!a!list!of!jobs!
• Get?Job*–ID*x*–ShowChildJob!will!show!the!child!jobs!of!the!parent!job!having!ID!x!
• Receive?Job!will!receive!the!results!of!a!given!job;!use!–keep!to!retain!the!results!in!memory!
to!be!received!again!later!
• Remove?Job!will!delete!a!job!and!its!results!
• Stop?Job!will!try!to!terminate!a!job!
• Wait?Job!will!wait!until!a!specified!job!or!jobs!enters!a!specified!state!
Exercises
Write!down!your!answers!to!the!following!tasks:!
1. Start!a!local!job!that!runs!the!following!command!in!the!background:!
Dir#C:\#*Recurse#
!
!
!
2. Start!a!remote!job!that!targets!at!least!one!computer!(localhost!is!fine!if!that’s!all!you!have)!
and!runs!the!following!command!on!each:!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Get*EventLog#–LogName#Security#
!
!
!
3. If!the!job!you!started!in!Task!1!is!still!running,!stop!it.!
!
!
!
4. Take!the!results!from!the!job!you!started!in!Task!1,!and!put!those!results!into!a!text!file!
named!Dir.txt.!
!
!
!
5. Display!the!results!from!the!job!you!started!in!Task!2.!Make!sure!you!save!the!results!so!that!
you!can!display!them!again!later.!
!
!
!
6. ReAdisplay!the!results!from!the!job!you!started!in!Task!2.!This!time,!only!display!the!events’!
time!written,!index,!and!source.!
!
!
!
7. Create!a!scheduled!job!(not!a!scheduled!task!–!they!are!different!things)!that!runs!each!time!
the!computer!starts.!Have!the!scheduled!job!run!the!following!command:!
Get*CimInstance#–Class#Win32_OperatingSystem#|#
Select#LastBootUpTime#|##
Out*File#c:\BootTimes.txt#*Append#
After!creating!the!job,!save!all!open!documents!and!restart!your!computer!(run!Restart?
Computer).!After!restarting,!log!in!and!verify!that!BootTimes.txt!exists!and!contains!data.!
!
You!will!need!to!review!the!help!for!the!commands!in!the!PSScheduledJob!module!(Get?
Command*–Module*PSScheduledJob)!to!complete!this!task.!Multiple!commands!are!
required!to!create!the!job,!create!its!schedule!trigger,!and!so!on.!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
15 !
Shell Security
Background
Remember!that!the!shell’s!execution!policy!is!Restricted!on!client!computers,!and!on!Windows!
Server!2012!and!earlier.!The!execution!policy!only!controls!the!execution!of!scripts,!and!it!relates!to!
whether!or!not!the!script!is!signed!by!a!trusted!digital!certificate.!
Syntax Review
Use!Set?ExecutionPolicy!to!set!the!execution!policy!of!the!local!computer.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
For!the!purposes!of!this!class!only,!set!your!shell’s!execution!policy!to!Unrestricted.!This!will!still!
prompt!you!to!execute!remote!scripts,!but!it!will!not!check!for!signatures.!If!you!are!working!on!a!
production!computer!(like!your!own!laptop),!please!be!aware!of!organizational!policies!regarding!
this!setting.!Also!be!aware!that!an!active!GPO!can!override!your!local!setting;!you!may!need!to!run!
powershell.exe*–executionpolicy*unrestricted!to!start!a!shell!session!with!a!classAappropriate!
execution!policy.!
Then,!complete!the!following!tasks:!
1. Find!a!command!that!will!set!a!signature!in!a!script!file.!
!
!
!
2. Find!a!command!that!will!verify!the!integrity!of!a!signed!script!file.!
!
!
!
3. What!utility!can!be!used!to!generate!a!selfAsigned!test!certificate?!Hint:!this!information!is!in!
an!about_!file!that!covers!signing.!!
!
!
!
4. Display!a!list!of!all!certificates!stored!in!your!personal!(“My!Certificates”)!store!on!your!
computer.!
!
!
!
5. Use!Windows!Notepad!to!create!a!file!named!C:\Test.ps1.!In!it,!put!the!following!command.!
Then,!make!sure!you!can!run!the!file!from!PowerShell.!
Write*Host#"Script#execution#enabled"#–fore#green#
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
16 !
Parameterizing a Command
Background
You!should!always!start!by!running!commands!right!in!the!PowerShell!console.!That!is!the!easiest!
way!to!test!and!perfect!a!command!and!verify!its!output.!!
Then,!identify!hardcoded!values!that!may!need!to!change,!and!plan!to!turn!those!into!parameters.!
A!PowerShell!script!can!be!coded!to!accept!parameters,!and!insert!them!in!place!of!placeholders!
(variables)!in!the!command.!You!simply!run!the!script!and!provide!parameters,!just!as!you!have!
already!run!commands!that!accept!parameters.!
Syntax Review
A!script!parameter!block!takes!the!following!basic!form:!
[CmdletBinding()]#
Param(#
###[string]$Parameter1,#
#
###[int]$Parameter2#
)#
Aside!from!comments,!this!needs!to!be!the!first!thing!in!the!script!file,!or!PowerShell!will!not!
recognize!it.!
Parameter!names!should!not!be!“Parameter1”!and!“Parameter2;”!the!parameter!names!should!be!
meaningful,!should!indicate!what!they’re!for,!and!should!be!consistent!with!the!other!commands!in!
PowerShell.!For!example,!a!parameter!that!accepts!a!computer!name!should!probably!be!called!
ComputerName.!
Notice!that!all!parameter!names!except!your!last!parameter!must!be!followed!by!a!comma.!If!you!
only!have!one!parameter,!then!there!will!be!no!comma!after!its!name,!because!it!is!the!last!parameter!
in!the!Param()!block.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Start!with!the!following!command:!
Get*CimInstance#–ComputerName#localhost#
################*ClassName#Win32_OperatingSystem#
################*Namespace#root\cimv2#
That!will!need!to!be!typed!on!a!single!line!in!order!to!run!correctly;!it!is!formatted!on!multiple!lines!
here!only!for!easier!reading.!
Run!the!command!and!ensure!that!it!works!correctly.!Then,!use!the!PowerShell!ISE!to!create!a!script!
named!C:\GetAOSInfo.ps1.!Add!this!command!to!the!script,!and!parameterize!the!computer!name.!
You!should!be!able!to!run!the!following!to!test!your!script:!
PS#C:\>#C:\Get*OSInfo#–ComputerName#localhost#
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
17 !
Designing a Tool
Background
Remember!the!differences!between!tools!and!controllers.%Also!remember!the!three!main!categories!of!
tools.!!
!
As!you!work!through!this!lab,!give!consideration!to!naming!conventions,!and!to!remaining!consistent!
with!the!way!Windows!PowerShell!works.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercise A
You!are!going!to!write!a!tool!that!gathers!information!from!one!or!more!remote!computers.!
Eventually,!you!will!have!the!tool!log!failed!computer!names!to!a!text!file,!and!so!you!will!want!a!way!
to!specify!that!filename.!The!tool!should!accept!strings!from!the!pipeline!as!one!way!of!specifying!
computer!names.!
The!tool!will!query!information!from!three!WMI/CIM!classes,!and!output!a!combined!object!that!
includes!some!properties!from!each!of!those!three.!Some!of!the!property!names!will!be!renamed!in!
the!final!output.!
Class*Name* Original*Property*Name* Output*Property*Name*
Win32_OperatingSystem* CSName! ComputerName!
* Version! OSVersion!
* BuildNumber! OSBuild!
* ServicePackMajorVersion! SPVersion!
Win32_ComputerSystem* Manufacturer! Mfgr!
* Model! Model!
Win32_BIOS* SerialNumber! BIOSSerial!
!
Complete!the!following!design!form,!describing!the!specifics!of!your!tool:!
TOOL!NAME!
!
!
INPUT!PARAMETERS!AND!PARAMETER!TYPES!
!
!
!
!
DESIGN!NOTES!
!
!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercise B
You!are!going!to!write!a!tool!that!gathers!information!from!one!or!more!remote!computers.!
Eventually,!you!will!have!the!tool!log!failed!computer!names!to!a!text!file,!and!so!you!will!want!a!way!
to!specify!that!filename.!The!tool!should!accept!strings!from!the!pipeline!as!one!way!of!specifying!
computer!names.!
This!tool!will!start!by!querying!the!Win32_Service!class!for!all!running!services.!Each!service!has!a!
property!that!contains!the!ID!number!of!the!corresponding!process.!You!will!then!query!that!instance!
of!the!Win32_Process!class.!Your!output!will!include!the!following:!
Class*Name* Original*Property*Name* Output*Property*Name*
* ! ComputerName!
Win32_Service* Name! ServiceName!
Win32_Process* Name! ProcessName!
!
Complete!the!following!design!form,!describing!the!specifics!of!your!tool:!
TOOL!NAME!
!
!
INPUT!PARAMETERS!AND!PARAMETER!TYPES!
!
!
!
!
DESIGN!NOTES!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
18 !
The Scripting Language
The If Construct
The!full!form!of!the!If!construct!is:!
If#($this#–eq#$that)#{#
####do#this#
}#ElseIf#($those#–eq#$these)#{#
####do#this#instead#
}#Else#{#
####do#this#only#
}#
You!may!have!zero!or!more!ElseIf!blocks,!and!zero!or!one!Else!block.!!
Create!a!new!script!file!in!the!PowerShell!ISE.!Start!the!script!with!the!following!command:!
$age#=#Read*Host#"Enter#your#age"#
Complete!the!script!so!that!it!displays!the!following:!
• For!ages!under!18,!display!“you’re!still!a!kid”!
• For!ages!18A64,!display!“welcome!to!adulthood”!
• For!ages!65!and!over,!display!“enjoy!your!retirement”!
Run!the!script!to!test!your!code.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
ForEach#($single#in#$many)#{#
####use#$single#here#
}#
The!second!variable!($many!in!the!example)!is!expected!to!be!a!collection!of!one!or!more!items.!The!
first!variable!($single!in!the!example)!will!contain!one!item!at!a!time!within!the!construct.!There!are!
no!technical!rules!for!the!variable!names,!but!it!is!common!to!use!singular!and!plural!variants!that!
describe!what!the!variables!contain,!such!as!ForEach*($user*in*$users).!!
Create!a!new!script!file!in!the!PowerShell!ISE.!Start!the!script!with!the!following!command:!
$disks#=#Get*CimInstance#–Class#Win32_LogicalDisk#–filter#"DriveType=3"#
Complete!the!script!so!that!it!calculates!the!free!space!percentage!(free!space!divided!by!size),!and!
then!outputs!a!warning!(use!WriteAWarning)!for!any!drives!with!less!than!10%!free!space.!The!
warning!should!include!the!drive!letter!and!the!free!space!percentage.!
To!test!your!script,!you!may!want!to!temporarily!change!the!threshold!from!10%!to!99%,!so!that!you!
will!see!output.!
!
While#($this#*eq#$that)#{#
####do#something#
}#
The!loop!will!only!execute!if!the!condition!is!true!to!begin!with,!and!will!continue!to!execute!while!
that!condition!remains!true.!
Create!a!new!script!file!in!the!PowerShell!ISE.!Start!the!script!with!the!following!command:!
$continue#=#$True#
Complete!the!script!so!that!it!uses!ReadAHost!to!display!a!prompt,!“Enter!QUIT!to!quit.”!Continue!to!
reAdisplay!the!prompt!until!the!user!enters!QUIT.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Switch#($thing)#{#
##1#######{###do*this#}#
##2#######{###or*that#}#
#'C'######{###or*this#}#
##default#{###nah*this#}#
}#
The!Switch!construct!is!good!for!examining!a!single!item!and!taking!different!actions!based!on!its!
contents.!
Create!a!new!script!file!in!the!PowerShell!ISE.!Start!the!script!with!the!following!command:!
$action#=#Read*Host#"Enter#an#action,#Logoff#or#Poweroff"#
Complete!the!script!so!that!it!uses!a!Switch!construct!to!examine!the!value!of!$action.!Use!WriteA
Warning!to!display!an!appropriate!message:!
• For!Logoff,!display!“Logging!off.”!
• For!Poweroff,!display!“Powering!off.”!
• For!any!other!value,!display!“Unknown!action.”!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
$adapters#=#Get*NetAdapter#*Physical#
foreach#($adapter#in#$adapters)#{#
####$addresses#=#Get*NetIPAddress#*InterfaceIndex#($adapter.InterfaceIndex)#
####foreach#($address#in#$addresses)#{#
########$properties#=#@{'Adapter'=$adapter.Name;#
########################'IPAddress'=$address.IPAddress;#
########################'AddrFamily'=$address.AddressFamily}#
########$obj#=#New*Object#*TypeName#PSObject#*Property#$properties#
########Write*Output#$obj#
####}#
}##
Some!things!to!notice:!
• The!object!is!produced!inside!the!innermost!ForEach!construct,!since!that!is!the!only!location!
where!all!of!the!desired!information!is!available.!
!
• The!output!properties!are!not!in!the!same!order!as!specified!in!the!script.!.NET!Framework!
uses!a!memoryAefficient!hash!table!to!store!these;!we!will!specify!better!default!formatting!in!
an!upcoming!lab.!
!
• When!querying!adapters!and!addresses,!there!is!no!need!to!use!SelectAObject!to!select!the!
properties!you!want.!You!make!those!selections!when!you!assemble!the!hash!table.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
19 !
Advanced Functions, Part 1
Background
In!this!lab,!you!will!create!an!advanced!function!for!each!exercise.!Both!functions!can!be!included!in!
the!same!script!file.!
Remember!that!running!the!script!will!not!run!the!functions.!Also!remember!that!it!is!the!functions,!
not!the!scripts,!that!accept!input!parameters.!To!test!a!function,!you!will!need!to!add!a!line!to!the!very!
end!of!the!script.!That!line!should!run!the!function,!including!whatever!parameters!you!want!to!test.!
For!now,!name!your!script!file!C:\MyTools.ps1.!!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Syntax Review
Here!is!an!example!advanced!function!that!includes!the!features!you!have!learned!about!so!far:!
Function#Get*NetworkAdapterInfo#{#
####[CmdletBinding()]#
####Param(#
########[string]$ComputerName#
####)#
#
######start#CIM#session#to#computer#
####$session#=#New*CimSession#*ComputerName#$ComputerName#
#
######query#adapters#
####$adapters#=#Get*NetAdapter#*Physical#*CimSession#$session#
####foreach#($adapter#in#$adapters)#{#
#
##########query#addresses#for#this#adapter#
########$addresses#=#Get*NetIPAddress#*ifIndex#($adapter.InterfaceIndex)#*Cim#$session#
########foreach#($address#in#$addresses)#{#
#
##############create#output#
############$properties#=#@{'Adapter'=$adapter.Name;#
############################'IPAddress'=$address.IPAddress;#
############################'AddrFamily'=$address.AddressFamily#
############################'ComputerName'=$ComputerName}#
############$obj#=#New*Object#*TypeName#PSObject#*Property#$properties#
############Write*Output#$obj#
########}#
####}#
#
####$session#|#Remove*CimSession#
}##
Exercise A
Create!an!advanced!function!that!implements!your!design!for!Exercise!A.!!
• Be!sure!to!include!a!parameter!for!the!error!log!file,!although!you!will!not!yet!use!the!
parameter.!
• Perform!your!three!WMI/CIM!queries!up!front,!saving!their!results!into!variables.!Then,!use!
those!variables!to!create!the!output!object.!
Exercise B
Create!an!advanced!function!that!implements!your!design!for!Exercise!A.!!
• Be!sure!to!include!a!parameter!for!the!error!log!file,!although!you!will!not!yet!use!the!
parameter.!
• Perform!your!first!CIM/WMI!query,!saving!its!results!to!a!variable.!You!will!then!need!to!
enumerate!the!objects!in!that!variable,!since!there!will!be!more!than!one.!
• Perform!your!second!CIM/WMI!query,!savings!its!results!to!a!variable.!Because!this!should!
contain!only!one!object,!you!should!not!need!to!enumerate!it.!!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
20 !
Advanced Functions, Part 2
Background
In!this!lab,!you!will!make!a!number!of!significant!changes!to!your!advanced!function.!You!will!still!
need!to!test!each!function!individually,!and!do!so!by!adding!a!line!that!runs!a!function!to!the!end!of!
your!script.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Syntax Review
The!following!example!includes!all!of!the!features!you!learned!about!in!this!unit.!Changes!from!the!
previous!example!are!more!prominent.!
Function#Get*NetworkAdapterInfo#{#
####[CmdletBinding()]#
####Param(#
!!!!!!!![Parameter(ValueFromPipeline=$True,Mandatory=$True)]!
!!!!!!!![Alias('cn')]!
!!!!!!!![ValidateCount(1,5)]!
########[string[]]$ComputerName,#
#
!!!!!!!![switch]$LeaveSessions!
####)#
!!!!BEGIN!{}!
!!!!PROCESS!{!
!!!!!!!!foreach!($computer!in!$computername)!{!
##############start#CIM#session#to#computer#
############$session#=#New*CimSession#*ComputerName#$Computer#
#
##############query#adapters#
############$adapters#=#Get*NetAdapter#*Physical#*CimSession#$session#
############foreach#($adapter#in#$adapters)#{#
#
##################query#addresses#for#this#adapter#
################$addresses#=#Get*NetIPAddress#*ifIndex#($adapter.InterfaceIndex)#*Cim#$session#
################foreach#($address#in#$addresses)#{#
#
######################create#output#
####################$properties#=#@{'Adapter'=$adapter.Name;#
####################################'IPAddress'=$address.IPAddress;#
####################################'AddrFamily'=$address.AddressFamily#
####################################'ComputerName'=$Computer}#
####################$obj#=#New*Object#*TypeName#PSObject#*Property#$properties#
####################Write*Output#$obj#
################}##foreach#address#
############}##foreach#adapter#
#
!!!!!!!!!!!!if!(Qnot!($LeaveSessions))!{!
################$session#|#Remove*CimSession#
!!!!!!!!!!!!}!
!!!!!!!!}!#foreach!computer!
!!!!}!#PROCESS!
!!!!END!{}!
}##
Notice!the!following:!
• The!–ComputerName!parameter!now!accepts!multiple!values.!
• The!–ComputerName!parameter!accepts!values!from!the!pipeline!ByValue.!
• The!–ComputerName!parameter!is!mandatory.!
• The!–ComputerName!parameter!accepts!1A5!values!only.!
• The!–ComputerName!parameter!has!an!alias,!ACN.!
• The!–LeaveSessions!parameter!is!new,!and!is!a![switch]!parameter!(True/False).!
• BEGIN,!PROCESS,!and!END!blocks!are!added!to!support!pipeline!input.!
• A!ForEach!construct!has!been!added!to!enumerate!multiple!computer!names.!
• The!two!uses!of!$ComputerName!are!now!$Computer,!to!correspond!with!the!ForEach!
construct.!
• An!If!construct!has!been!added!that!will!leave!CimSessions!connected!if!specified.!Notice!that!
the!$session!variable!still%goes%out%of%scope!when!the!function!ends,!and!so!the!CimSessions!
do%not!remain!connected!after!the!function!ends.!This!has!been!added!to!demonstrate!that!
behavior!of!scope.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
In!both!Exercise!A!and!Exercise!B,!make!the!following!changes:!
• Change!your!–ComputerName!parameter!so!that…!
o It!is!mandatory!
o It!accepts!one!or!more!strings!from!the!pipeline!
o It!accepts!multiple!values!
o It!has!an!alias,!AHostName!
• Modify!the!function!body!to!support!pipeline!input!and!multiple!computer!names!
Test!your!function!by!piping!strings!to!it.!For!example:!
"localhost","localhost"#|#Do*Whatever#
Replacing!“DoAWhatever”!with!your!own!function!name,!of!course.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
21 !
Discovering Commands
Background
Saving!scripts!as!a!script!module!can!make!testing!easier.!It!also!makes!your!script!easier!to!
distribute!to,!and!share!with,!others,!and!makes!the!functions!in!your!script!easier!to!use.!
Exercises
Follow!these!steps:!
1. Remove!all!code!in!your!script!that!is!not!inside!a!function.!This!includes!removing!any!lines!
that!call!your!functions,!that!you!may!have!been!using!to!test!them.!
!
!
2. Save!your!script!as!C:\Program!
Files\WindowsPowerShell\Modules\MyTools\MyTools.psm1.!!
!
Note!that!this!path!only!works!on!PowerShell!v4!and!later.!If!you!are!using!an!earlier!version!
of!PowerShell,!save!your!script!in!your!Documents!folder,!under!
\WindowsPowerShell\Modules\MyTools\MyTools.psm1.!!
!
If!you!do!this!correctly,!the!green!“run”!icon!in!the!ISE!toolbar!will!be!grayed!out.!
!
!
3. Open!a!new!PowerShell!console.!Try!to!run!your!commands.!You!should!not!need!to!put!a!
path!on!the!command!name,!and!both!the!command!name!and!the!commands’!parameters!
should!tabAcomplete.!
From!now!on,!remember!that!any!changes!to!your!script!must!be!saved.!You!must!also!unload!your!
module!by!running!Remove?Module*MyTools,!before!running!your!commands!again.!If!you!do!not,!
your!changes!will!not!be!loaded!into!memory.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
22 !
Comment-Based Help
Background
For!more!information,!read!about_comment_based_help!in!the!shell.!
Although!commentAbased!help!can!appear!in!several!locations,!the!easiest!one!to!work!with!is!
immediately%after!your!function’s!opening!curly!bracket,!and!before!the![CmdletBinding()]!attribute.!
There!may!be!no!other!comments!in!that!area.!
CommentAbased!help!keywords!are!not!caseAsensitive,!although!it!is!customary!to!type!them!in!allA
uppercase.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Syntax Review
This!excerpt!shows!the!commentAbased!help!for!our!running!example,!GetANetworkAdapterInfo.!Pay!
close!attention!to!the!.PARAMETER!and!.EXAMPLE!sections.!
Function#Get*NetworkAdapterInfo#{#
<#!
.SYNOPSIS!
Retrieves!network!adapter!and!IP!address!information!
.DESCRIPTION!
GetQNetworkAdapterInfo!uses!CIM!to!connect!to!remote!
computers,!which!in!turn!requires!that!Remoting!(WinRM)!
be!enabled.!
.PARAMETER!ComputerName!
One!or!more!computer!names,!as!listed!in!Active!Directory.!
.PARAMETER!LeaveSessions!
Leave!CIM!sessions!connected!for!the!duration!of!the!command.!
.EXAMPLE!!
"localhost","server"!|!GetQNetworkAdapterInfo!
.EXAMPLE!
GetQNetworkAdapterInfo!QComputerName!ONE,TWO!
#>!
####[CmdletBinding()]#
####Param(##
Exercises
Add!commentAbased!help!to!all!of!the!functions!in!your!script!module.!At!a!minimum,!add:!
• A!synopsis!
• A!description!
• Help!for!each!parameter!
• Two!examples!
Save!your!script!module.!In!a!new!PowerShell!console!window,!test!your!help!by!asking!for!full!help!
on!your!commands.!Also!test!your!help!with!the!–ShowWindow!parameter.!
What!additional!commentAbased!help!sections!do!you!think!might!be!useful?!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
23 !
Handling Errors
Background
Remember!that!setting!$ErrorActionPreference!globally!is!considered!a!poor!practice.!Instead,!set!
the!error!behavior!on!a!perAcommand!basis!by!using!the!–ErrorAction*(AEA)!parameter!supported!
by!all!commands.!Its!settings!include!SilentlyContinue,!Continue,!Inquire,!and!Stop.!Only!Stop!
causes!commands!to!produce!a!trappable,!terminating!exception.!
It’s!okay!to!set!$ErrorActionPreference!when!you’re!running!something!other!than!a!command,!such!
as!a!.NET!Framework!method.!Just!be!sure!to!set!it!back!to!the!default,!Continue,!afterwards.!
There!are!several!ways!to!capture!the!actual!error!as!you’re!handling!it:!
• The!$?!variable!will!contain!True/False!based%on%what%the%lastOrun%command%reported%as%its%
success.%This!isn’t!usually!considered!reliable!in!terms!of!error!handling.!
!
• The!$_!variable!will!contain!the!most!recent!error!when!used!in!a!Catch!block.!However,!you!
should!immediately!copy!that!to!another!variable,!since!$_!may!quickly!get!used!for!other!
purposes!by!the!shell.!
!
• The!$error[0]!item!will!be!the!most!recent!error.!
!
• You!can!specify!a!variable!by!running!commands!and!using!the!common!–ErrorVariable!(?
EV)!parameter.!
Each!of!these!techniques!works!slightly!differently!and!provides!somewhat!different!information!–!
experiment!to!see!what!works!best!in!a!given!situation.!Read!The%Big%Book%of%PowerShell%Error%
Handling!for!more!details!and!examples.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Syntax Review
The!following!function!illustrates!several!errorAhandling!concepts!and!techniques.!
Function#Get*NetworkAdapterInfo#{#
<##
.SYNOPSIS#
Retrieves#network#adapter#and#IP#address#information#
.DESCRIPTION#
Get*NetworkAdapterInfo#uses#CIM#to#connect#to#remote#
computers,#which#in#turn#requires#that#Remoting#(WinRM)#
be#enabled.#
.PARAMETER#ComputerName#
One#or#more#computer#names,#as#listed#in#Active#Directory.#
.PARAMETER#LeaveSessions#
Leave#CIM#sessions#connected#for#the#duration#of#the#command.#
.EXAMPLE##
"localhost","server"#|#Get*NetworkAdapterInfo#
.EXAMPLE#
Get*NetworkAdapterInfo#*ComputerName#ONE,TWO#
#>#
####[CmdletBinding()]#
####Param(#
########[Parameter(ValueFromPipeline=$True,Mandatory=$True)]#
########[Alias('cn')]#
########[ValidateCount(1,5)]#
########[string[]]$ComputerName,#
#
########[switch]$LeaveSessions,#
#
########[ValidateScript({#*not#(Test*Path#$_)#})]#
########[string]$ErrorLogFile#
####)#
####BEGIN#{}#
####PROCESS#{#
########foreach#($computer#in#$computername)#{#
##############start#CIM#session#to#computer#
############try#{#
################$session#=#New*CimSession#*ComputerName#$Computer#*ErrorAction#Stop#
#
##################query#adapters#
################$adapters#=#Get*NetAdapter#*Physical#*CimSession#$session#
################foreach#($adapter#in#$adapters)#{#
#
######################query#addresses#for#this#adapter#
####################$addresses#=#Get*NetIPAddress#*ifIndex#($adapter.InterfaceIndex)#*Cim#$session#
####################foreach#($address#in#$addresses)#{#
#
##########################create#output#
########################$properties#=#@{'Adapter'=$adapter.Name;#
########################################'IPAddress'=$address.IPAddress;#
########################################'AddrFamily'=$address.AddressFamily#
########################################'ComputerName'=$Computer}#
########################$obj#=#New*Object#*TypeName#PSObject#*Property#$properties#
########################$obj.PSObject.TypeNames.Insert(0,'Corp.NetAdapterInfo')#
########################Write*Output#$obj#
####################}##foreach#address#
################}##foreach#adapter#
#
################if#(*not#($LeaveSessions))#{#
####################$session#|#Remove*CimSession#
################}#
############}#catch#{#
################$computer#|#Out*File#$ErrorLogFile#*Append#
################Write*Warning#"$computer#`n#$($error[0])"#
############}##Trycatch#
########}##foreach#computer#
####}##PROCESS#
####END#{}#
}##
Notice!how!the!$ErrorLogFile!parameter!is!defined!and!validated.!Also!notice!how!the!warning!
message!is!displayed.!Pay!close!attention!to!the!code!contained!within!the!Try!block!–!if!an!error!
occurs,!everything!else!in!the!Try!block!will!be!skipped,!preventing!any!further!query!attempts!and!
preventing!any!blank!output!for!this!computer.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Add!error!handling!to!your!functions.!Specifically:!
• At!the!top!of!your!module,!before!the!first!function,!define!a!$ErrorLogFilePreference!
variable!and!set!it!to!“C:\Errors.txt”.!!
!
• Make!sure!each!function!has!an!–ErrorLogFile!parameter.!The!parameter!should!default!to!
$ErrorLogFilePreference,!and!should!accept!a!single!string.!Do!not!make!it!mandatory.!
However,!use!a!parameter!validation!attribute!to!only!accept!filenames!that!do!not!exist.!
!
• Anticipate!that!a!computer!you!query!may!not!be!online!or!available.!Capture!the!resulting!
error,!and!log!the!computer!name!to!the!file!specified!in!$ErrorLogFile.!You!may!also!display!
a!warning!message.!However,!do!not!produce!any!other!output!for!the!failed!computer.!
Be!sure!to!test!your!modified!functions!in!a!new!PowerShell!console!window.!Specify!a!computer!or!
two!that!exists,!and!one!or!two!that!do!not.!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
24 !
Custom Formatting
Background
Custom!formatting!files!can!have!any!filename!you!want,!but!they!must!have!the!.format.ps1xml!
filename!extension.!
You!can!find!(and!copy!&!paste)!examples!in!
\Windows\System32\WindowsPowerShell\v1.0\DotNetTypes.format.ps1xml.!
Remember!that!you!can!only!apply!custom!formatting!to!an!object!that!has!a!unique!typename.!
Syntax Review
This!code!snippet!shows!how!to!add!a!custom!type!name!to!an!output!object:!
##create#output#
$properties#=#@{'Adapter'=$adapter.Name;#
################'IPAddress'=$address.IPAddress;#
################'AddrFamily'=$address.AddressFamily#
################'ComputerName'=$Computer}#
$obj#=#New*Object#*TypeName#PSObject#*Property#$properties#
$obj.PSObject.TypeNames.Insert(0,'Corp.NetAdapterInfo')#
Write*Output#$obj#
To!start!a!new!formatting!file,!open!a!new!script!in!the!PowerShell!ISE.!Immediately!save!the!script!
with!the!correct!filename,!so!that!the!ISE!will!colorAcode!the!XML!correctly.!!
Each!formatting!file!can!contain!views!for!multiple!object!types.!You!start!by!giving!the!file!it’s!header!
and!footer:!
<?xml#version="1.0"#encoding="utf*8"#?>#
<Configuration>#
####<ViewDefinitions>#
#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
####</ViewDefinitions>#
</Configuration>#
All!of!the!views!that!you!create!will!go!in!between!<ViewDefinitions>!and!</ViewDefinition>.!
Table!Views!
The!following!code!snippet!shows!an!example!of!a!table!view.!Notice!that!there!are!three!column!
headers.!The!last!column!header!is!a!singleton,!meaning!it!does!not!define!a!column!label,!a!width,!or!
an!alignment.!PowerShell!will!autoAcalculate!the!width!and!alignment,!and!will!use!the!property!
name!as!the!column!header.!
<View>#
####<Name>Corp.NetAdapterInfo</Name>#
####<ViewSelectedBy>#
########<TypeName>Corp.NetAdapterInfo</TypeName>#
####</ViewSelectedBy>#
#
####<TableControl>#
########<TableHeaders>#
#
############<TableColumnHeader>#
################<Label>IPAddr</Label>#
################<Width>15</Width>#
############</TableColumnHeader>#
#
############<TableColumnHeader>#
################<Label>Adapter</Label>#
################<Width>14</Width>#
################<Align>Left</Align>#
############</TableColumnHeader>#
#
############<TableColumnHeader/>#
#
########</TableHeaders>#
#
########<TableRowEntries>#
############<TableRowEntry>#
################<TableColumnItems>#
#
####################<TableColumnItem>#
########################<PropertyName>IPAddress</PropertyName>#
####################</TableColumnItem>#
####################<TableColumnItem>#
########################<ScriptBlock>#$_.ToLower()#</ScriptBlock>#
####################</TableColumnItem>#
####################<TableColumnItem>#
########################<PropertyName>AddrFamily</PropertyName>#
####################</TableColumnItem>#
#
################</TableColumnItems>#
############</TableRowEntry>#
############</TableRowEntries>#
####</TableControl>#
</View>##
There!are!several!other!things!to!notice:!!!
• You!would!add!more!<TableColumnHeader></TableColumnHeader>!items!to!add!more!
headers.!
• Each!header!must!have!a!corresponding!<TableColumnItem></TableColumnItem>.!
• Some!table!column!items!simply!refer!to!properties!of!the!object!being!formatted.!Other!
column!items!are!script!blocks!that!execute!code,!such!as!the!second!column!here.!That!one!
produces!a!lowercase!version!of!the!property’s!contents.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
List!Views!
List!views!are!simpler.!Here!is!an!example:!
<View>#
####<Name>My.Whatever.Object</Name>#
####<ViewSelectedBy>#
########<TypeName>My.Whatever.Object</TypeName>#
####</ViewSelectedBy>#
########<ListControl>#
########<ListEntries>#
############<ListEntry>#
################<ListItems>#
#
####################<ListItem>#
########################<PropertyName>Name</PropertyName>#
####################</ListItem>#
#
####################<ListItem>#
########################<PropertyName>WidgetProperty</PropertyName>#
####################</ListItem>#
#
####################<ListItem>#
########################<PropertyName>Speed</PropertyName>#
####################</ListItem>#
#
################</ListItems>#
############</ListEntry>#
########</ListEntries>#
####</ListControl>#
</View>##
You!do!not!define!headers!and!items!separately,!here.!Instead,!you!simply!list!out!the!properties.!
Be!Careful!
The!<TypeName></TypeName>!element!must!contain!the!exact!same!type!name!that!you!gave!your!
custom!object!in!your!function.!It!is!customary!for!the!<Name></Name>!element!to!contain!the!same!
thing,!but!technically!that!element!can!contain!any!string!you!wish.!
Testing!Your!View!
When!you’re!ready!to!test!your!view,!you!must!load!it!into!memory.!For!example:!
PS#C:\>#Update*FormatData#–Append#MyCustomView.format.ps1xml#
You!must!do!this!in!each!new!console!window!that!you!open.!If!you!get!an!error,!or!want!to!make!
other!changes,!close!the!console!window!and!open!a!new!one!to!try!again.!Don’t!forget!to!reload!the!
view!in!each!new!console!window.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercise A
Give!your!output!object!a!custom!type!name,!MyTools.OSInfo.!Create!a!table!display!that,!by!default,!
shows!only!the!ComputerName,!Version,!and!BIOSSerial!properties.!Configure!the!column!widths!to!
waste!as!little!horizontal!space!as!possible.!
Save!the!file!in!the!same!folder!as!your!MyTools.psm1!module.!Be!sure!to!test!it.!
Exercise B
Give!your!output!object!a!custom!type!name,!MyRTools.ServiceProcessInfo.!Create!a!list!display!
that,!by!default,!shows!the!ComputerName,!ServiceName,!and!ProcessName!properties.!
This!should!go!in!the!same!file!as!your!Exercise!A!custom!view.!Be!sure!to!test!it.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
25 !
Manifest Modules
Background
When!PowerShell!tries!to!load!a!module,!it!goes!to!the!module’s!folder.!It!looks!for!three!files,!which!
must!have!the!module’s!name!as!their!main!filename,!and!which!each!have!a!different!filename!
extension.!They!are:!
• modulename.psd1!
• modulename.dll!
• modulename.psm1!
So!far,!you!have!relied!on!the!.psm1!file!existing!–!your!script!module.!The!.psd1!is!a!manifest,!and!
allows!the!shell!to!load!more!than!one!file!as!part!of!a!module.!
Syntax Review
Use!the!New?ModuleManifest!command!to!create!a!manifest.!It!is!often!easiest!to!change!into!the!
module’s!folder!first.!Note!that!the!syntax!for!this!command!is!different!in!PowerShell!v2;!the!v3+!
syntax!is!shown!here.!
PS#C:\Program#Files\WindowsPowerShell\Modules\MyTools>##
New*ModuleManifest#–Path#MyTools.psd1#
###################*RootModule#MyTools.psm1#
###################*FormatsToProcess#MyToolsFormatting.format.ps1xml#
Notice!that!the!.psd1!filename!must%match!the!module’s!name,!which!is!also!the!name!of!the!folder!in!
which!the!module!lives.!The!–RootModule!is!your!script!module!.psm1!file.!This!example!also!
specifies!a!custom!formatting!file,!like!the!one!you!created!in!the!previous!unit.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Create!a!module!manifest!that!loads!your!script!module!and!your!custom!formatting!view!–!
eliminating!the!need!to!run!UpdateAFormatData!separately.!
Test!your!module!by!opening!a!new!PowerShell!console!window!and!running!one!of!your!module’s!
commands.!The!default!formatting!should!display!automatically.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
26 !
Supporting ShouldProcess
Background
Remember!that!a!command!must!declare!support!for!ShouldProcess.!Declaring!enables!the!–WhatIf!
and!–Confirm!parameters.!The!command!must!also!implement!that!support.!
The!Win32_OperatingSystem!class!(in!CIM!or!WMI)!has!a!method!named!Win32Shutdown.!For!
example,!in!this!lab,!you!will!use!the!following!to!execute!the!method:!
$os#=#Get*WmiObject#–Class#Win32OperatingSystem#–Computer#SERVER#
$os.Win32Shutdown(4)#
In!this!example,!the!argument!given!is!4.!Valid!values!are:!
• 0!–!Log!off!
• 1!–!Shut!down!
• 2!–!Restart!
• 8!–!Power!off!
If!4!is!added!to!any!of!these,!the!operation!is!forced.!For!example,!4!is!a!forced!log!off,!and!5!is!a!
forced!shutdown.!
Syntax Review
Refer!to!unit!18!for!reminders!on!how!to!use!the!Switch!construct.!You!will!need!that!in!this!exercise.!
To!declare!support!for!ShouldProcess:!
[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]#
ConfirmImpact!is!your!personal!judgment!of!how!devastating!the!command!might!be,!expressed!as!
“Low,”!“Medium,”!or!“High.”!Keep!in!mind!that,!by!default,!a!confirm!impact!of!“High”!means!that!the!
command!will!automatically!run!as!if!–Confirm!was!specified.!That!can!be!annoying.!
To!implement!support!for!ShouldProcess,!you!wrap!your!“potentially!dangerous”!code!in!an!If!
construct:!
If#($PSCmdlet.ShouldProcess("message"))#{#
####dangerous#commands#go#here#
}#
The!“message”!should!give!a!clear!indication!of!what%is%about%to%be%modified.%Your!command!name!
will!become!part!of!the!message,!and!will!indicate!what%is%about%to%happen.!Remember!that!the!If!
construct!should!contain!all!commands!that!might!actually!make!some!kind!of!change!to!the!system.!
That!way,!if!the!command!is!run!by!using!–WhatIf,!no!changes!will!actually!be!made.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Remember!that!you!can!read!about_functions_advanced_parameters!to!learn!more!about!the!
[ValidateSet()]!parameter!validation!attribute.!
Exercises
Write!a!new!command!called!SetAComputerState.!If!you!have!already!created!a!script!module,!add!the!
command!to!that!module.!!
Your!command!must!accept!the!following!parameters:!
• AComputerName!must!accept!one!or!more!computer!names!or!IP!addresses!
• AForce!must!be!a![switch]!parameter!
• AAction!must!accept!a!string,!and!it!must!only!accept!the!values!“LogOff,”!“Restart,”!
“Shutdown,”!or!“PowerOff.”!
• AWhatIf!and!AConfirm!
For!each!computer!specified,!your!command!must!run!the!specified!action.!For!example:!
Set*ComputerState#–Computer#ONE,TWO#–Action#LogOff#–Force#
This!would!run!Win32Shutdown(4)!against!the!computers!ONE!and!TWO.!The!4!is!derived!because!
the!action!specified!is!“LogOff”!(value!0),!and!–Force!was!specified!(add!4!to!the!action!value).!You!
will!use!a!Switch!construct!in!your!command!to!translate!the!string!action!to!its!numeric!value.!
Your!command!should!have!a!confirm!impact!of!Medium.!If!it!is!run!with!–WhatIf,!it!should!take!no!
action,!but!should!instead!specify!what!it!would!have!done,!and!to!which!computer!or!computers.!
Similarly,!if!it!is!run!with!–Confirm,!it!should!prompt!for!each!computer!before!taking!action.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
27 !
Debugging Scripts
Background
Debugging!usually!involves!checking!a!script’s!property!values!and!variable!contents.!Most!logic!
errors!can!be!traced!to!values!that!are!other!than!those!you!may!have!expected.!By!checking!the!
values!as!the!script!runs,!you!can!confirm!or!correct!your!expectations.!
Syntax Review
You!can!use!Write?Debug!to!add!debug!output!and!breakpoints!to!a!script.!It!works!best!in!scripts!or!
functions!that!use![CmdletBinding()],!which!enables!the!–Debug!parameter!for!the!script!or!
function.!Running!the!script!or!function!with!–Debug!will!enable!WriteADebug.!
You!can!also!use!Set?PSBreakpoint!to!set!breakpoints.!!
Inside!the!ISE,!you!can!move!the!cursor!to!a!line!and!press!F9!to!toggle!a!breakpoint!on!that!line.!
When!you!run!the!script!and!encounter!a!breakpoint,!you!can!enter!Suspend!mode!(happens!
automatically!with!ISE!and!SetAPSBreakpoint!breakpoints).!In!Suspend!mode,!you!can!examine!the!
values!in!variables!or!properties,!run!commands,!and!otherwise!validate!your!expectations.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
You!may!want!to!complete!this!exercise!on!your!host!machine,!if!it!has!Internet!connectivity!and!is!
running!at!least!Windows!8.!You!may!use!your!virtual!machine!if!it!has!Internet!connectivity.!!
Download!the!example!script!from!http://bit.ly/1o0EjeC!(note!that!this!URL!is!caseAsensitive!and!
contains!the!number!1,!a!lowercase!“O,”!and!the!number!zero)!and!open!it!in!the!Windows!
PowerShell!ISE.!!
Alternately,!if!you!do!not!have!Internet!connectivity!on!any!computer,!enter!the!following!in!a!script!
named!DebuggingLab.ps1:!
function#Get*LowSpaceVolumes#{#
[CmdletBinding()]#
Param(#
[Parameter(Mandatory=$True)]#
[string[]]$ComputerName,#
[int]$MinimumFreePercent#=#99)#
PROCESS#{#
ForEach#($Computer#in#$ComputerName)#{#
$session#=#New*CimSession#*ComputerName#$ComputerName#
Get*Volume#*CimSession#$session#|#
Where*Object#{#$_.DriveType#=#3#*and#`#
($_.FreeSpace#/#$_.Size#*#100#*lt#$MinimumFreePercent)#}#
$session#|#Remove*CimSession#
}}}}#
#
Get*LowSpaceVolumes#*ComputerName#localhost,localhost##
When!run,!this!script!has!errors!and!does!not!produce!any!output.!When!corrected,!it!should!produce!
output!when!run!asAis.!
Note!that!a!debugged!version!of!the!script!is!included!on!the!next!page!for!your!convenience.!Please!
do!not!refer!to!that!as!a!shortcut!–!it!is!important!that!you!go!through!the!process!of!finding!these!
bugs!on!your!own.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Answer
This!is!the!debugged!script.!
function#Get*LowSpaceVolumes#{#
####[CmdletBinding()]#
####Param(#
########[Parameter(Mandatory=$True)]#
########[string[]]$ComputerName,#
#
########[int]$MinimumFreePercent#=#99#
####)#
####PROCESS#{#
########ForEach#($Computer#in#$ComputerName)#{#
#############
############$session#=#New*CimSession#*ComputerName#$Computer#
#
############Get*Volume#*CimSession#$session#|#
############Where*Object#{#$_.DriveType#*eq#'Fixed'#*and#($_.SizeRemaining#/#$_.Size#*#100#*lt#$MinimumFreePercent)#}#
#
############$session#|#Remove*CimSession#
#
########}#
####}#
}#
#
Get*LowSpaceVolumes#*ComputerName#localhost##
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
28 !
Tracing Commands
! 20 minutes lecture
!! 20 minutes lab "! Client virtual machine only
#! PowerShell 2+ !
$! Windows 7+ !
Syntax Review
As!a!reminder,!the!first!example!in!the!help!for!Trace?Command!demonstrates!how!to!use!the!
command!for!parameter!binding!troubleshooting.!Briefly:!
PS#C:\>#Trace*Command#–Expression#{#command*to*trace#}#
######################*PSHost#–Name#ParameterBinding,Cmdlet#
Exercises
Explain!what!is!happening!with!the!pipeline!input!from!this!command:!
PS#C:\>#"DC","localhost"#|##
########Invoke*Command#–Script#{#Get*EventLog#–LogName#Security#}#
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
!
31 !
Controller Scripts:
Tech Menus
! 20 minutes lecture
!! 20 minutes lab "! Client virtual machine only
#! PowerShell 3+ !
$! Windows 8+ !
Background
This!kind!of!controller!script!is!designed!to!display!a!textAbased!menu!to!a!help!desk!or!other!support!
technician.!It!provides!them!an!easy!way!of!selecting!and!running!predefined!tools.!Scripts!of!this!
kind!usually!do!not!have!a!cmdletAstyle!name.!If!they!do!have!a!cmdletAstyle!name,!the!verb!portion!of!
the!name!is!usually!“Show,”!indicating!that!the!script!relies!on!the!screen!and!keyboard!for!human!
interaction.!
Syntax Review
Use!Write?Host!and!Read?Host!to!display!and!collect!input.!Switch!constructs!are!often!helpful!for!
running!different!commands!based!on!the!user’s!selection.!
When!commands!are!capable!of!prompting!for!input!on!their!own,!you!may!want!to!run!them!
without!parameters!and!simply!let!them!do!their!own!prompting.!Otherwise,!you!may!want!to!
prompt!for!parameter!values,!save!them!to!variables,!and!then!feed!those!variables!to!the!command’s!
parameters!when!running!it.!
Exercises
Write!a!technician!menu!that!offers!the!ability!to!do!the!following!to!the!local!computer:!
• Display!a!list!of!physical!network!adapters,!including!adapter!alias,!interface!index,!MAC!
address,!and!link!speed.!
!
• Display!a!list!of!all!local!IP!addresses.!
!
• Display!the!operating!system!version,!service!pack!version,!BIOS!serial!number,!and!
computer!manufacturer!and!model.!
!
• Restart!a!specified!service!by!name!–!prompt!for!the!service!name,!and!allow!only!a!single!
service!name.!
After!running!the!specified!task,!the!menu!should!reAdisplay!until!the!technician!selects!an!option!to!
exit.!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
32 !
Controller Scripts:
HTML Reports
! 30 minutes lecture !! Creating HTML Reports in PowerShell
!! 30 minutes lab "! Client virtual machine only
#! PowerShell 2+ !
$! Windows 7+ !
Background
Most!HTML!reports!are!created!to!include!multiple!sections.!To!do!so,!you!must!start!be!creating!an!
HTML%fragment!for!each!section.!The!sections!can!then!be!combined!to!form!a!complete!report.!The!
complete!report!may!additionally!include!a!Cascading!Style!Sheet!(CSS)!and!other!information.!
This!unit!uses!only!native!PowerShell!functionality.!More!advanced,!enhanced!HTML!reports!are!
covered!in!unit!33,!which!may!or!may!not!be!covered!in!your!class.!
Syntax Review
Assume!you!want!to!run!two!tools,!GetAOSInfo!and!GetAProcess,!and!turn!the!output!of!each!tool!into!
the!section!of!an!HTML!report.!Start!by!creating!the!HTML!fragments:!
$frag1#=#Get*OSInfo#–ComputerName#WHATEVER#|#
#########ConvertTo*HTML#–Fragment#–As#Table#–PreContent#"<h2>OS</h2>"#|#
#########Out*String#
#
$frag2#=#Get*Process#–ComputerName#WHATEVER#|#
#########ConvertTo*HTML#–Fragment#–As#Table#–PreContent#"<h2>Procs</h2>"#|#
#########Out*String#
You!might!also!define!a!simple!CSS:!
$css#=#@"#
<style>#
body#{#
##font*family:Tahoma;#
##font*size:10pt;#
}#
th#{#
##background*color:black;#
##color:white;#
##font*weight:bold;#
}#
</style>#
"@#
You!would!then!create!the!final!report!as!follows:!
ConvertTo*HTML#–Body#"<h1>Report</h1>",$frag1,$frag2#–Head#$css#|#
Out*File#Report.html#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Write!a!controller!script!that!accepts!one!or!more!computer!names!as!input.!For!each!specified!
computer,!generate!an!HTML!report!file.!The!report!filename!should!be!<computername>.html,!
based!upon!the!computer!names!specified.!
In!each!report,!include!a!section!for!each!tool!in!the!script!module!that!you!created!in!units!17A25!of!
this!class.!If!you!did!not!complete!those!modules,!then!you!may!omit!those!sections!of!your!report.!
Each!report!must!also!include:!
• Currently!running!processes!on!the!computer,!showing!the!process!ID!and!name.!
• Current!services!on!the!computer,!showing!the!service!name,!display!name,!and!status.!
Each!section!of!the!report!should!include!an!<h2>!style!header,!as!shown!in!the!example!above.!The!
overall!report!should!include!an!<h1>!header!that!shows!the!computer!name.!Each!report!should!
also!include!a!simple!embedded!CSS,!as!shown!in!the!example.!
Test!the!script,!and!view!the!results!in!Internet!Explorer.!
You!can!also!experiment!with!this!expanded!CSS:!
$css#=#@"#
<style>#
body#{#
##font*family:Tahoma;#
##font*size:10pt;#
}#
th#{#
##background*color:black;#
##color:white;#
##font*weight:bold;#
}#
h1#{#
##text*align:center;#
##border*bottom:1px#solid#black;#
}#
h2#{#
##background*color:#ddd;#
}#
</style>#
"@#
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
33 !
Controller Scripts:
Enhanced HTML Reports
! 30 minutes lecture !! Creating HTML Reports in PowerShell,
from http://powershell.org/wp/ebooks
!! 45 minutes lab "! Client virtual machine only
#! PowerShell 2+ !
$! Windows 8+ !
Background
Enhanced!HTML!reports!consists!of!enhanced%HTML%fragments!and!a!final!enhanced%HTML%page.%Each!
fragment!is!used!to!create!one!section!of!the!final!report.!Each!fragment,!or!section,!can!have!its!own!
heading,!and!contain!its!own!data.!Typically,!you!use!a!single!tool!to!produce!a!single!fragment.!You!
then!combine!several!fragments!into!the!final!page.!
For!this!to!work,!you!will!need!two!JavaScript!files.!By!default,!the!EnhancedHTML2!module!will!pull!
these!from!Microsoft’s!Content!Delivery!Network!(CDN).!However,!that!required!Internet!
connectivity.!If!your!virtual!machine!does!not!have!Internet!connectivity,!then!you!may!need!to!copy!
the!resulting!HTML!report!to!your!host!computer,!or!to!another!computer!that!has!Internet!
connectivity.!
Syntax Review
There!are!three!main!tasks!you’ll!need!to!know.!
Creating!an!HTML!Fragment!
Here!is!an!example!of!creating!a!fragment,!using!the!GetAProcess!command:!
########$params#=#@{'As'='Table';#
####################'PreContent'='<h2>Processes</h2>';#
####################'EvenRowCssClass'='even';#
####################'OddRowCssClass'='odd';#
####################'MakeHiddenSection'=$true;#
####################'MakeTableDynamic'=$true;#
####################'Properties'='Name','ID',#
######################@{n='VM';e={$_.VM#/#1MB#–as#[int]};#
########################css={#if#($_.VM#–gt#1MB)#{#'red'#}}}#
########$fragment1#=#GetQProcess#|#
#####################ConvertTo*EnhancedHTMLFragment#@params#|#
#####################Out*String#
Note!the!following:!
• The!As!parameter!can!be!List!or!Table!
• PreContent!is!used!to!define!a!section!header;!here,!the!<h2>!HTML!tag!is!used!
• The!EvenRowCssClass!and!OddRowCssClass!are!given!CSS!class!names!
• MakeHiddenSection!can!be!$True!or!$False;!when!$True,!the!section!is!collapsed!by!default!
• MakeTableDynamic!will!make!the!table!pageable,!searchable,!and!sortable!
• The!Properties!list!includes!the!Name!and!ID!properties.!It!also!creates!a!custom!property!
named!VM.!This!includes!the!process!objects’!VM!property,!divided!by!1MB!and!cast!as!an!
integer.!Values!greater!than!1MB!will!have!the!CSS!class!“red”!applied!to!the!table!cell.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Creating!a!CSS!Style!Sheet!
You!can!use!the!following!CSS!style!sheet!as!an!example.!Just!add!this!to!your!controller!script:!
$style#=#@"#
<style>#
//#main#font#and#colors#
body#{#
####color:#333333;#
####font*family:Calibri,Tahoma;#
####font*size:#10pt;#
}#
.red#{#color:red;#}#
//#headings#
h1#{#
####text*align:center;#
}#
h2#{#
####border*top:1px#solid##666666;#
}#
#
//#table#style#
th#{#
####font*weight:bold;#
####color:#eeeeee;#
####background*color:#333333;#
####cursor:pointer;#
}#
#
//#classes#for#odd/even#table#rows#
.odd##{#background*color:#ffffff;#}#
.even#{#background*color:#dddddd;#}#
</style>#
"@#
Notice!that!the!variable!$style!holds!the!style!sheet.!Also!notice!that!.odd,!.even,!and!.red!are!defined!
CSS!classes.!These!same!classes!were!used!when!creating!the!HTML!fragment.!
Creating!the!Final!HTML!Page!
Suppose!that!you!have!created!two!HTML!fragments,!and!stored!them!in!$fragment1!and!
$fragment2.!You’ve!been!shown!how!to!do!that!above,!in!the!example!that!populated!$fragment1.!
Now!you!can!create!the!final!HTML!page:!
$params#=#@{'CssStyleSheet'=$style;#
############'Title'="System#Report";#
############'PreContent'="<h1>System#Report</h1>"#
############'HTMLFragments'=@($fragment1,$fragment2)}#
ConvertTo*EnhancedHTML#@params#|#
Out*File#*FilePath#C:\Output.html#
Notice!that!this!includes!$fragment1!and!$fragment2,!although!the!running!example!has!not!created!
a!$fragment2!–!you!would!be!expected!to!do!that.!This!applies!an!overall!<h1>!style!to!the!report!
heading,!and!attaches!the!CSS!style!sheet!we!put!into!$style.!
You!can!specify!two!other!parameters:!jQueryDataTableUri!and!jQueryUri!can!be!HTTP!or!UNC!
paths!to!the!two!JavaScript!files.!If!you!do!not!provide!these,!they!will!be!pulled!from!the!Microsoft!
CDN.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Exercises
Create!a!controller!script!that!has!a!parameter!block.!It!should!accept!one!or!more!computer!names!
as!its!first!parameter.!The!second!parameter!should!be!a!folder!path.!Include!a!validation!attribute!
that!only!accepts!folder!paths!that!already!exist.!
It!should!then!enumerate!those!computer!names,!and!create!one!report!HTML!file!for!each!computer.!
The!filename!for!each!file!should!be!a!computer!name,!with!an!.html!filename!extension.!The!files!
should!be!saved!in!the!designated!folder!path.!
Each!report!should!include!a!report!header,!and!four!report!sections:!
• Several!properties!from!the!Win32_OperatingSystem!WMI/CIM!class,!in!a!list!
• Running!processes,!in!a!dynamic!table!
• Services,!in!a!dynamic!table!
• The!most!recent!10!Security!event!log!entries,!in!a!nonAdynamic!table!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
43 !
DSC Configurations
Background
A!DSC!configuration!consists!of!a!main!configuration!element,!one!or!more!node!elements,!and!one!
or!more!configuration!settings.!When!you!run!a!configuration,!Windows!PowerShell!produces!a!MOF!
file.!That!MOF!file!is!what!you!deploy!to!the!target!node!in!order!to!configure!it.!
Syntax Review
The!following!is!an!example!configuration.!Notice!that!the!node!name!is!parameterized!by!defining!a!
–ComputerName!parameter!than!accepts!one!or!more!computer!names.!
Configuration#Sample#{#
####Param(#
########[string[]]$ComputerName#
####)#
#
####Node#$ComputerName#{#
#
########WindowsProcess#RegServer#{#
############Path###=#'C:\OurApps\RegLOB.exe'#
############Ensure#=#'Present'#
########}##windowsprocess#RegServer#
#
########Group#LOBAdmins#{#
############GroupName########=#'LOB#Administrators'#
############Ensure###########=#'Present'#
############Description######=#'Admins#of#the#LOB#application'#
############MembersToInclude#=#'Administrators'#
########}##group#LOBAdmins#
#
####}##node#
}##configuration##
This!configuration!contains!two!settings,!named!RegServer!and!LOBAdmins.!The!first!uses!the!
WindowsProcess!resource,!and!ensures!that!a!process!is!running.!The!second!uses!the!Group!
resource,!and!ensures!that!a!local!user!group!exists!and!is!populated.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
This!configuration!example!does!not!use!the!DependsOn!property!of!any!items.!DependsOn!allows!
you!to!specify!a!dependency.!For!example,!the!LOBAdmins!item!might!include:!
DependsOn="[WindowsProcess]RegServer"#
If!it!did,!then!the!LOBAdmins!item!would!not!be!processed!until!after!the!RegServer!item!was!
completed.!
Remember:!Simply!running!the!script!that!contains!a!configuration!will!not!run!the!configuration!
itself.!You!might,!for!example,!include!a!line!at!the!end!of!the!script!file!that!runs!the!configuration!
and!passes!it!any!needed!parameters.!
Also!remember!that!you!can!run!Get?DscResource!to!display!a!list!of!installed!DSC!resources.!To!
display!the!properties!for!a!specific!resource,!such!as!the!File!resource,!run:!
Get*DscResource#File#|#Select#–Expand#Properties#
After!you!have!created!and!run!a!configuration,!you!will!have!a!MOF!file.!The!configuration!will!
create!a!folder!that!has!the!same!name!as!the!configuration!itself.!Inside!that!folder,!it!will!create!a!
MOF!file!for!each!targeted!node.!If!you!run!the!configuration!inside!the!PowerShell!ISE,!pay!close!
attention!to!the!folder!that!the!ISE!is!in,!because!that!is!where!the!configuration!folder!will!be!
created.!
Use!Start?DscConfiguration!to!push!the!configuration.!You!must!provide!the!path!to!the!
configuration!folder;!by!default,!all!MOFs!in!that!folder!will!be!pushed!to!their!respective!nodes.!
Specify!–Wait!to!interactively!watch!the!push!operation.!
Exercises
Create!a!configuration!named!Lab.!Provide!a!–ComputerName!parameter!that!accepts!one!or!more!
string!values.!In!the!configuration,!target!all!nodes!specified!in!the!parameter.!!
Include!the!following!configuration!items:!
• Ensure!that!the!BITS!service!is!present!and!running,!and!is!set!to!run!automatically.!
!
• Ensure!a!local!group!named!“Help!Desk!Techs”!exists.!
!
• Ensure!a!local!user!named!“Help!Desk!Tech”!exists,!and!belongs!to!the!“Help!Desk!Techs”!
group.!
Run!the!configuration!and!target!your!local!machine.!If!you!have!your!server!VM!running,!target!it!
also.!Then!push!the!MOF!to!the!targeted!nodes.!Check!back!after!about!15!minutes!to!see!if!the!
configuration!changes!have!been!made.!
As!you!develop!this!configuration,!think!carefully.!There!are!dependencies!that!will!need!to!be!
documented!by!means!of!the!DependsOn!property!in!at!least!one!of!the!configuration!items.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
98 !
Review Exercises
Unit 1
1. Find!a!command!that!would!let!you!set!the!network!connection!profile!of!a!given!network!
adapter!to!“Public”!or!“Private.”!
!
!
!
2. Find!a!command!that!would!let!you!modify!the!caching!mode!of!a!file!(SMB)!share.!
!
!
!
3. What!module!would!enable!you!to!work!with!Windows!PowerShell!scheduled%jobs?!Is!that!
the!same,!or!different!than,!a!module!that!work!configure!the!Windows!Task!Scheduler?!
!
!
!
4. Find!(but!do*not*run)!a!command!that!would!remove!all!partition!information!from!a!disk!
and!completely!deAinitialize!that!disk.!
!
!
!
5. Is!there!a!command!that!can!resolve!a!DNS!host!name!to!its!IP!address?!
!
!
!
6. The!old!ipconfig*/flushdns!command!clears!the!client!DNS!cache.!Is!there!a!native!
PowerShell!command!that!does!the!same!thing?!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 2
1. The!following!command!is!intended!to!display!a!list!of!processes!running!on!a!remote!
computer!named!DC.!Will!it!work?!If!not,!how!would!you!rewrite!it!so!that!it!works!as!
described?!
PS#C:\>#Get*Process#*#DC#
!
!
!
2. Without!running!the!command!(you!can!read!the!command’s!help),!will!the!following!
command!display!a!list!of!event!logs!from!the!computer!named!DC?!
PS#C:\>#Get*EventLog#–Comp#DC#*Li#
!
!
!
3. Why!will!the!following!command!not!work!to!query!WMI!classes!from!a!remote!computer!
named!DC?!
PS#C:\>#gwmi#win32_service#–c#DC#
!
!
4. Run!a!command!that!will!display!only!physical!network!adapters.!A!single!command!should!
do!this.!
!
!
!
5. Run!a!command!that!will!display!all!local!IPv4!addresses!for!all!network!adapters.!
!
!
!
6. Run!a!command!that!will!display!all!IPv4!routes!that!are!defined!on!the!local!computer.!
!
!
!
!!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 4
1. Run!a!command!that!displays!all!services.!Then,!run!a!second!set!of!commands!that!will!put!
the!exact!same!information,!in!the!same!format,!into!a!text!file.!
!
!
!
!
2. Create!a!pipeAdelimited!file!(like!a!CSV,!but!using!a!|!character!instead!of!a!comma)!
containing!a!list!of!running!processes.!Make!sure!the!file!does!not!contain!a!comment!above!
the!header!row.!
!
!
!
3. What!formats!is!Windows!PowerShell!natively!able!to!convert!things!to?!
!
!
!
!
4. Can!you!find!a!command!capable!of!comparing!two!objects,!or!two!collections!of!objects?!
!
!
!
!
5. Run!the!following!commands.!Then,!write!and!run!a!single!command!that!will!compare!the!
contents!of!1.xml!and!2.xml,!considering!only!the!“Property”!column!in!each,!and!showing!
only!the!differences.!Note:!You!will!not!use!GetAContent!(or!any!aliases!thereof)!to!complete!
this.!
PS#C:\>#Get*Process#|#Export*CliXML#1.xml#
PS#C:\>#MSPaint#
PS#C:\>#Get*Process#|#Export*CliXML#2.xml#
PS#C:\>#Stop*Process#MSPaint#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 6
1. Run!the!following!command.!Then,!add!commands!so!that!the!output!includes!only!the!
DeviceID,!FreeSpace,!Size,!and!FreePercent.!Express!FreeSpace!and!Size!in!GB,!and!have!the!
FreePercent!column!show!the!percentage!of!free!space.!You!will!need!to!calculate!that!
percentage.!
PS#C:\>#Get*CimInstance#–Class#Win32_LogicalDisk#–Filter#"drivetype=3"#
!
!
!
!
2. Run!the!following!command.!Then,!add!commands!so!that!the!output!shows!the!computer!
name,!the!OS!build!number,!and!the!OS!architecture.!Display!the!OS!architecture!as!“32”!or!
“64,”!not!“32Abit”!or!“64Abit.”!
PS#C:\>#Get*CimInstance#–Class#Win32_OperatingSystem#
!
!
!
3. Display!the!first!five!services,!sorted!alphabetically!by!service!name,!whose!names!start!with!
“S.”!
!
!
!
4. Display!the!current!date!and!time!in!“Short!File!Format.”!
!
!
!
5. Display!the!total!amount!of!VM,!PM,!and!CPU!for!all!currently!running!processes.!Also!
include!a!count!of!the!number!of!processes.!You!should!use!only!two!commands!to!do!this,!
and!SelectAObject!will!not!be!one!of!them.!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 7
For!these!tasks,!describe!whether!or!not!the!command!will!work!as!intended,!and!describe!why!or!
why!not.!You!may!read!the!help!for!these!commands,!but!do!not!run!these!commands!to!see!if!they!
work!or!not.!You!may!run!underlined!commands!and!pipe!them!to!GetAMember.!
!
1. Retrieve!a!list!of!hotfixes!from!all!computers!listed!in!Computers.txt.!
Get*Content#Computers.txt#|#Get*Hotfix#
!
!
!
2. If!Inventory.csv!contains!a!“Name”!column,!and!if!that!column!contains!computer!names,!
retrieve!a!list!of!all!services!from!those!computers.!If!this!will!not!work,!rewrite!the!
command!so!that!it!will.!
Import*CSV#Inventory.csv#|#Get*Service#
!
!
!
!
!
3. If!Computers.txt!lists!one!computer!name!per!line,!retrieve!the!most!recent!50!Security!event!
log!entries!from!each!computer.!If!this!will!not!work,!rewrite!the!command!so!that!it!will.!
Get*Content#Computers.txt#|#Get*EventLog#–Log#Security#–New#50#
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 8
These!tasks!show!truncated!example!output!from!a!command.!Using!FormatA*!commands,!reproduce!
this!output!as!closely!as!possible.!Notice!that!your!property!values!will!obviously!differ!from!these!
examples;!recreate!the!overall!appearance!of!these!examples!as!closely!as!possible.!
!
1. Process!list,!in!order!by!ID:!
##Id#Name#################VM#####PM#
##**#****#################**#####**#
###0#Idle###############0.06###0.00#
###4#System#############4.41###0.11#
#176#iexplore#########155.99##12.04#
#376#LiveComm#########986.52##11.90#
#488#smss###############4.17###0.28#
#508#svchost##########194.71##34.42#
#592#csrss#############48.06###2.11#
#608#svchost##########120.88###8.82#
#660#csrss############175.86###2.11#
#668#wininit###########40.29###0.80#
#696#winlogon##########55.22###1.41#
#752#services##########37.73###4.91#
#760#lsass#############41.74###5.46#
#820#iexplore#########220.25##16.15#
#824#WWAHost##########913.36##40.22#
!
!
!
2. List!of!disk!volumes:!
Driveletter###:#
DriveType#####:#Fixed#
SizeRemaining#:#113971200#
#
Driveletter###:#C#
DriveType#####:#Fixed#
SizeRemaining#:#46809174016#
#
Driveletter###:#A#
DriveType#####:#Removable#
SizeRemaining#:#0#
#
Driveletter###:#D#
DriveType#####:#CD*ROM#
SizeRemaining#:#0#
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
3. Recently!run!commands!and!their!execution!time:!
Id#TimeElapsed######CommandLine#
**#***********######***********#
#1#00:00:07.6289526#get*module#*ListAvailable#
#2#00:00:00.2800996#gcm#*Module#NetConnection#
#3#00:00:01.0608366#Get*NetConnectionProfile#
#4#00:00:00.9635337#help#Set*NetConnectionProfile#
#5#00:00:01.1838088#get*command#*Module#SmbShare#
#6#00:00:00.7012523#help#Set*SmbShare#
#7#00:00:01.7784241#gcm#*Module#Storage#
#8#00:02:57.8093943#help#clear*disk#
#9#00:00:00.1431763#help#Block*SmbShareAccess#
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 9
1. Display!a!list!of!hotfixes!that!were!installed!by!someone!other!than!Administrator,!or!by!an!
unknown!user.!If!your!computer!does!not!contain!any!hotfixes,!skip!this!task.!
!
!
!
2. Display!a!list!of!event!log!entries!(use!Security!or!Application,!if!they!contain!entries)!from!
today!only.!Do!not!use!the!–Newest!parameter!of!GetAEventLog,!but!complete!this!task!in!a!
single!command!line!(which!may!contain!multiple!commands).!You!will!need!to!use!a!
command!that!can!retrieve!the!current!date.!
!
!
!
!
!
3. Display!a!list!of!all!recently!run!commands!that!took!less!than!00:00:07.000!to!run.!You!will!
need!to!first!calculate!elapsed!time,!then!filter!on!that!calculated!property.!
!
!
!
!
!
4. Use!Get?Volume!to!display!a!list!of!only!local!hard!disks!and!their!information.!
!
!
!
!
5. Display!a!list!of!installed!Windows!optional!features.!
!
!
!
!
6. Starting!in!HKEY_CURRENT_USER,!display!a!list!of!all!keys!that!contain!the!word!“Microsoft.”!
This!may!take!a!while!to!run,!so!you!may!want!to!open!a!new!console!window!for!this!one,!so!
it!can!continue!running.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Units 1 through 9
1. Find!and!run!a!command!that!will!display!a!random!number.!
!
!
!
2. !Using!the!command!you!found!in!the!previous!task,!write!a!new!commandAline!that!will!
display!only!the!name!of!a!random!service!on!your!computer.!
!
!
!
3. Use!the!Get?ChildItem!command!to!display!a!list!of!all!installed!certificates!on!your!
computer.!
!
!
!
4. Create!an!HTML!report!showing!all!installed!hotfixes.!Include!the!hotfix!ID!number,!the!date!
it!was!installed!(if!available),!and!the!name!of!the!user!that!installed!it!(if!available).!!
!
!
!
5. Find!a!command!that!can!display!SMB!shares.!Do!the!objects!produced!by!that!command!
offer!a!way!to!see!if!the!share!is!enabled!for!Shadow!Copy?!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 13
1. Display!a!list!of!all!CIM!class!names!that!include!the!word!“service.”!
!
!
!
2. What!are!the!differences!between!the!CIM_Service!and!Win32_Service!classes?!Do!they!have!
the!same!instances?!
!
!
!
!
!
3. Display!a!list!of!classes!in!the!root\SecurityCenter2!namespace.!How!many!of!these!classes!
return!instances!on!your!computer?!
!
!
!
!
4. Write!a!command!that!would!establish!a!DCOMAbased!CIM!session!to!an!older!computer!
named!WINXP.!You!do!not!need!to!run!this!command.!
!
!
!
!
5. What!methods!exist!on!the!Win32_OperatingSystem!class?!
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Unit 16
Turn!the!following!command!into!a!parameterized!script.!Notice!that!this!command!uses!a!
hardcoded!value!as!a!threshold.!You!should!parameterize!that!value,!as!well!as!the!computer!name.!
When!tested!using!the!hardcoded!value,!you!might!not!see!any!results.!Try!using!different!thresholds!
when!you!test,!to!see!what!results!you!get.!
Get*WmiObject#–ClassName#Win32_LogicalDisk#|#
Where*Object#{#$_.FreeSpace#/#$_.Size#*#100#–lt#10#}#
Your!parameterized!script!does!not!need!to!be!a!function.!Save!the!script!as!GetA
DisksHavingLowSpace.ps1.!!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
! !
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
!
!
!
Windows PowerShell
Education
Designed by Don Jones
!
!
!
!
!
!
!
!
!
For*more*information,*or*to*book*
your*class,*contact*us*at*ConcentratedTech.com*
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Welcome
Don!Jones,!the!world’s!most!wellAknown!and!soughtAafter!Windows!PowerShell!instructor,!designed!
Concentrated!Tech’s!Windows!PowerShell!Education.!Based!on!his!Nine%Principles%of%Immediately%
Effective%Instruction,%our!courses!are!designed!to!make!Microsoft!administrators!more!efficient!in!
their!production!environments,!as!quickly!as!possible.!
Our!courses!are!designed!to!be!very!modular,!enabling!you!to!select!the!modules!that!best!meet!your!
most!pressing!production!needs.!However,!be!advised!that!we!teach!the!core%PowerShell%technology%
only.%We!do!not!teach!Exchange!Server,!SharePoint,!Lync,!or!any!of!the!many!other!PowerShellA
enabled!products.!We!believe!that!our!course!“teaches!you!to!fish”!rather!than!just!“feeding!you!fish,”!
meaning!after!completing!our!course!you!should!be!effective!in!any!product!that!is!PowerShellA
enabled.!By!not!focusing!on!productAspecific!details,!we!can!instead!focus!tightly!on!PowerShell!itself,!
accommodating!a!wider!range!of!students!and!helping!them!better!learn!and!retain!these!key!skills.!
Booking Window
Please!be!advised!that!we!often!book!up!to!9!months!in!advance.!We!may!have!availability!on!shorter!
notice,!but!the!further!ahead!you!can!plan,!the!better.!We!have!only!a!small!number!of!licensed!
instructors!who!deliver!our!courseware!according!to!our!high!standards!and!practices.!
Class Times
We!usually!start!class!at!9am!and!end!by!4pm!or!5pm.!We!plan!to!end!early,!often!by!lunchtime,!on!
the!last!day!of!a!fullAweek!class.!The!extra!time!allows!us!to!handle!differences!in!the!pace!of!
individual!students!within!the!class.!We!allow!1!hour!for!lunch,!bringing!each!day!to!6A7!hours!of!
instruction.!We!find!that!pushing!the!day!earlier!or!later!tends!to!result!in!markedly!lowered!
retention!and!comprehension.!
We!typically!have!a!minimum!class!length!of!3!days,!usually!priced!at!$2500/day!(US!domestic)!plus!
travel!expenses,!for!up!to!20!students.!Don!Jones!is!available!for!5Aday!engagements!at!$15,000/week!
(US!domestic)!plus!travel!expenses.!
Class Materials
We!provide!you!with!a!PDF!file!of!our!lab!guide,!which!is!customized!for!your!delivery!outline.!You!
will!need!to!print!that!for!your!students’!use!in!class,!and!you!may!distribute!it!within!your!own!
organization!to!other!interested!employees.!
We!also!offer!class!kits.!These!include:!
• Learn%Windows%PowerShell%in%a%Month%of%Lunches,!a!foundationAlevel!tutorial!that!aligns!to!
the!course!content!
• Learn%PowerShell%Toolmaking%in%a%Month%of%Lunches,%an!intermediateAlevel!tutorial!and!
reference!that!aligns!to!the!course!content!
• PowerShell%in%Depth,!a!deep!reference!on!everything!in!PowerShell!
• A!spiralAbound!lab!guide!that!includes!all!42!unit!labs!–!even!ones!that!might!not!be!covered!
in!your!particular!class,!thereby!providing!your!students!with!additional!selfAdirected!
learning!opportunities.!!
These!kits!are!just!$115!per!student!plus!shipping.!Please!allow!a!4!week!lead!time!for!book!kits.!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Start!with!the!Basics!
Unless!your!students!already!have!a!strong!and%correct!understanding!of!PowerShell!fundamentals,!
we!recommend!using!units!1A16!in!order.!This!takes!about!2!to!2.5!days!for!most!classes.!We!find!that!
many!students!who!believe!they!understand!PowerShell!well!actually!don’t;!they’ve!merely!picked!up!
bad!habits!by!reading!stuff!online.!An!especially!bright!group!can!move!through!units!1A6!in!1!to!1.5!
days,!if!needed.!
Move!into!BestGPractices!Modular!Automation!
If!your!goal!is!to!start!producing!reusable!automation!tools!according!to!best!practices,!units!17A27!
covers!that,!and!usually!takes!2!to!2.5!days.!For!classes!starting!more!or!less!from!scratch,!expect!
units!1A27!to!essentially!take!a!full!week.!!
Add!Advanced!Techniques!
Units!28A30!focus!on!advanced!Toolmaking!techniques,!and!can!often!be!included!in!a!oneAweek!class!
if!the!students!are!quick,!and!if!we!shorten!some!of!the!lab!times.!
Bring!it!Together!to!Automate!Processes!
Units!31A35!focus!on!using!tools!to!accomplish!productionAquality!tasks.!We!can!usually!include!2A3!
of!these!in!a!oneAweek!class,!if!we!skipped!units!28A30,!or!if!we’ve!severely!curtailed!lab!time!in!the!
introductory!units!(1A16).!
Cover!Niche!Topics!
Units!36A42!cover!advanced!topics!that!are!usually!needAspecific.!In!some!cases,!we!can!include!the!
lecture/demo!portion!of!these!on!an!“as!available”!basis!if!you!indicate!that!you’d!like!us!to!try!and!
do!so.!!
Explore!Desired!State!Configuration!
Units!43A45!cover!Desired!State!Configuration.!43!and!44!can!be!included!in!most!courses!and!
require!very!little!actual!PowerShell!experience;!unit!45!is!an!advanced!programming!topic!and!is!
best!completed!at!the!end!of!a!class,!and!only!if!students!have!some!prior!programming!background!
and!are!familiar!with!PowerShell!Toolmaking.!
Note!that!we!offer!other!DSCAspecific!training,!including!3Aday!workshops!and!halfAday!webAbased!
consultations.!Contact!us!through!www.ConcentratedTech.com!for!more!information.!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Outline
Times!shown!are!lecture/lab/minAlab.!In!other!words,!the!approximate!amount!of!lecture!time,!the!
ideal!amount!of!lab!time,!and!the!minimal!amount!of!lab!time!needed!to!cement!key!topics.!
When!time!permits,!we!typically!start!each!day!with!a!review!assignment!that!revisits!earlier,!critical!
material!to!help!reinforce!retention.!Review!periods!are!usually!allotted!30A45!minutes.!
PowerShell Fundamentals
Minimum&delivery&for&all&units:&10&hours.&
Ideal&delivery&time&for&all&units:&14&hours.&
Does¬&include&breaks/lunches.&
1. Discovering!Commands!
30/30/15!
2. Running!Commands!!
30/30/15!
3. Using!PSProviders!!
15/15/15!
4. Connecting!Commands!
20/30/15!
5. Extending!the!Shell!
15/20/0!
6. Working!with!Objects!
30/30/15!
7. Understanding!the!Pipeline!
30/30/15!
8. Formatting!
30/30/15!
9. Filtering!and!Comparisons!
30/30/15!
10. Enumerating!Objects!
15/30/15!
11. Variables!
30/30/15!
12. Remoting!and!PSSessions!
30/30/15!
13. WMI!and!CIM!
30/45/30!
14. Background!Jobs!
15/30/0!
15. Shell!Security!
15/15/0!
16. Parameterizing!a!Command!
15/15/15!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
PowerShell Toolmaking
Minimum&delivery&for&all&units:&7&hours.&
Ideal&delivery&time&for&all&units:&11&hours.&
Does¬&include&breaks/lunches.&
Units!17G26!are!an!integrated!series!and!are!not!offered!individually.!However,!your!outline!can!stop!at!
any!point!in!the!series,!if!don’t!want!to!cover!all!of!the!topics!offered.!Unit&27&can&be&offered&a&la&carte.&
17. Designing!a!Tool!
20/30/15!
18. The!Scripting!Language!
20/30/15!
19. Advanced!Functions,!Part!1!
20/60/30!
20. Advanced!Functions,!Part!2!
30/45/30!
21. Script!Modules!
15/15/15!
22. CommentABased!Help!
15/30/15!
23. Handling!Errors!
30/45/20!
24. Custom!Formatting!
30/45/20!
25. Manifest!Modules!
15/15/15!
26. Supporting!ShouldProcess!
15/30/0!
27. Debugging!Scripts!
30/45/0!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
33. Controller!Scripts:!Enhanced!HTML!Reports!
30/45!
34. Controller!Scripts:!Automated!Processes!
15/30!
35. Controller!Scripts:!Trend!Reports!
Requires!SQL!Server!Express!with!Advanced!Services!
30/45!
Advanced Topics
These&modules&are&added&a&la&carte.&Times&are&lecture/lab.&
36. Working!with!XML!
30/45!
37. Directly!Accessing!SQL!Server!Data!
Requires!SQL!Server!Express!
30/45!
38. Workflow!Overview!
30/0!
39. (forthcoming)!Regular!Expressions!
40. (forthcoming)!Retrieving!Data!from!the!Web!
41. (forthcoming)!Using!.NET!Framework!Classes!
42. (forthcoming)!PowerShell!Web!Access!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Recommended Outline
We!recommend!the!following!for!an!accelerated!5Aday!class,!with!students!who!are!familiar!with!
Windows!administration!but!who!need!a!solid!grounding!in!PowerShell:!
Day 1
• 1!Discovering!Commands!!
• 2!Running!Commands!!
• 3!Using!PSProviders!!
• 4!Connecting!Commands!
• 5!Extending!the!Shell!
• 6!Working!with!Objects!
• 7!Understanding!the!Pipeline!
• 8!Formatting!
• 9!Filtering!and!Comparisons!
Day 2
• Day!1!Review!
• 10!Enumerating!Objects!
• 11!Variables!
• 12!Remoting!and!PSSessions!
• 13!WMI!and!CIM!
• 14!Background!Jobs!
• 15!Shell!Security!
• 16!Parameterizing!a!Command!
!
Day 3
• Day!1A2!Review!
• Designing!a!Tool!
• The!Scripting!Language!
• Advanced!Functions,!Part!1!
• Advanced!Functions,!Part!2!
• Script!Modules!
• CommentABased!Help!
!
Day 4
• Handling!Errors!
• Custom!Formatting!
• Manifest!Modules!
• Supporting!ShouldProcess!
• Debugging!Scripts!
• Tracing!Commands!
• Controller!Scripts:!Tech!Menus!
• Controller!Scripts:!HTML!Reports!
!
Day 5
• Controller!Scripts:!Automated!Processes!
• DSC!Configurations!
• DSC!Pull!Servers!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*
!
Lab Environment
We!require!that!each!student!have!his!or!her!own!lab!computer.!We!provide!a!complete!lab!setup!
guide,!and!for!a!small!fee!can!provide!readyAbuilt!virtual!machine!images!in!VMware!format!(suitable!
for!use!with!VMware!Player!or!VMware!Workstation).!
Each!student!should!have!a!Windows!Server!2012!R2!Server!Core!computer!that!is!configured!as!a!
domain!controller.!They!should!also!have!a!domainAjoined!Windows!8.1!client!computer.!The!virtual!
machines!need!to!talk!to!each!other,!and!they!do!not!require!Internet!connectivity.!We!do!require!
that!you!make!sure!hotfix!KB2883200!is!installed!on!both!virtual!machines.!We!provide!an!ISO!image!
with!everything!else!students!will!need!in!class!–!this!ISO!can!be!attached!to!the!virtual!DVD!drive!of!
the!client!computer.!Please!contact!us!for!details.!
!
!
! Copyright*2014*Concentrated*Technology,*LLC.*Duplication*without*written*permission*is*prohibited.*
AfterAclass*Q&A*is*handled*in*the*forums*at*PowerShell.org.*