Learn about Windows PowerShell
Summary: The Scripting Wife adds a function to her Windows PowerShell profile to update the Sysinternals tools on her computer.
Microsoft Scripting Guy Ed Wilson here. I had completed my IT Time radio interview with Blain Barton for my series on Windows PowerShell best practices, when I heard the commotion from downstairs. I quickly donned my trench coat and hat, and eased into the hallway. The following photo is of me on the prowl.
I eased into the kitchen, and spotted the Scripting Wife at her keyboard. She looked up at me, and stared.
“You look like Knute Rockne in that outfit,” she said, “I need help with my profile.”
“A profile? Write one for the Gipper,” I said.
“Anyway, the panel discussion with Mark Russinvoch is tomorrow afternoon at Bouchercon. I was curious, about getting the Sysinternals tools installed on my computer. But I am also curious about keeping them up to date, because I know he updates them quite regularly,” she said.
“So you want to install the Sysinternals tools on your computer?”
“And you would like to have an easy way to update the tools from time to time?”
“Yes. You know Mark is cool. He signed my copy of Zero Day for me at Tech∙Ed,” she said as she showed me the following photo from her computer (thanks to Ron Taylor from Ottawa for taking this photo and sharing it with me).
“Yes, I know. How come you don’t keep pictures of me signing my Windows PowerShell 2.0 Best Practices book for you,” I asked.
“Well, for one thing, I don’t have any pictures of you signing my copy of your book. For a second thing, I don’t need your autograph on the book—I am in the dedication,” she said matter-of-factly.
“Okay. Makes sense. About your problem of downloading, and installing the Sysinternals tools, I have found a really cool script called Get-Sysinternals on the Scripting Guy’s Script Repository. Unfortunately, the copy code button does not work for this script, but I was able to highlight the text field, and paste it into the Windows PowerShell ISE. I then ran it, and it created a directory off the Windows Directory, and copied all the files there. It also edited your path statement so that you can easily use the tools,” I said.
“Okay. Show me the script, and its output,” she said.
I turned the monitor so that she could see the Windows PowerShell ISE and the associated output. It is shown in the following figure.
“That is pretty cool. But how could I put that in my profile? I don’t want that great big monster script in my profile.”
“Well, the first thing to do is to save the script to your Windows PowerShell profile directory. You could then dot-source it into your profile, but the script does not play well with others. So we will take a different approach. First open your Windows PowerShell console profile in Notepad by using the Set-Profile function you added yesterday.”
Note This is part four of a four-part series on the Scripting Wife and the Windows PowerShell profile. On Monday, she created a profile for the Windows PowerShell console. On Tuesday, she created a profile for the Windows PowerShell ISE. On Wednesday, she formatted the profile file and added a Set-Profile function to her Windows PowerShell console profile.
“Okay, now what?” she asked. Her Windows PowerShell console profile is shown in the following figure.
“Copy the entire contents of your Windows PowerShell console to your Windows PowerShell ISE profile. First, copy the Windows PowerShell console profile to the clipboard.”
The Scripting Wife clicked Notepad to ensure it was active. Then she pressed CTRL+A to select all contents of the Windows PowerShell profile in Notepad. Then she pressed CTRL+C to copy the profile to Clipboard. She pressed CTRL+A, and then she pressed CTRL+C to copy it to Clipboard.”
After the Scripting Wife had copied the contents of her Windows PowerShell console profile to her Windows PowerShell ISE profile, it was time to add a variable and a function.
“Why do I need to add a variable?” asked the Scripting Wife.
“Because it will make things a bit easier. You want to be able to access your script without having to do a lot of extra work. There is already the $profile variable that points to the Windows PowerShell profiles in your Windows PowerShell directory in your normal user profile. I want you to create a variable that points only to the Windows PowerShell directory inside your user profile.”
“I see,” she said.
“In the # Variable section of profile, create a new variable named $myPsHome, and set it equal to the parent portion of the $profile variable. The parent portion of the $profile variable refers to the directory in which the Windows PowerShell profile file is located. To split the path that is contained in the $profile variable, you will want to use the Split-Path cmdlet,” I instructed.
I could see the word huh forming on her brow for just a few seconds. Then I could see by the word eureka gradually replacing the word huh. I bet the Scripting Wife did not realize her forehead contained an LED display. She lowered her head and began to type. Slowly, surely, and with confidence, her keystrokes gathered speed. The command she typed is shown here:
$myPsHome = Split-Path -path $profile –parent
The exact keystrokes she typed are shown here:
“Very good. Now, what you want to do is to create a custom function to launch your Get-Sysinternals.ps1 script,” I said.
“Why do I have to do that?” she asked.
“Well, you don’t. But because of the way the script is written, you cannot dot-source it into your Windows PowerShell profile. It will run the entire script every time you open Windows PowerShell. If the script had a main function you could call when you wanted to run the script, you could just dot-source it,” I explained.
“I see,” she said in a tentative voice.
“You could simply type the full path to the script every time you wanted to run the script, but that could be a pain because the script requires administrator rights. Therefore, when you open Windows PowerShell with administrator rights, it drops you into the Windows\System32 directory. I really do not want you messing around in that directory,” I said.
“That’s good. I don’t want to hose my computer,” she said.
“Hose?” I asked.
“Yes, it is a computer term. It stands for ‘hardware or software error,’” she said.
I began to wonder with whom she had been chatting during the PowerScripting Podcast.
“Okay, now that you have the variable for $myPsHome, create a function. You can call the function Get-SysInternals. Inside the function, you will use the Invoke-Expression cmdlet to invoke the Get-SysInternals.ps1 script from within your Windows PowerShell folder from within your user profile,” I said.
She thought about it for a minute, and finally she typed the function. Here is the function she created.
} #end get-sysinternals
The Scripting Wife’s revised Windows PowerShell ISE profile is shown in the following figure.
“Now, close your Windows PowerShell ISE, and open it again but with administrator rights. To do this, hold down Shift, and right-click the Windows PowerShell ISE icon. Next, click “Run as Administrator” in the shortcut menu. In the command pane, type Get-SysInternals and press Enter. This will run your custom function and call the script to update any Sysinternals tools that have changed since the last time you ran the script,” I said.
“Okay. This is easy now,” she said.
The Scripting Wife opened the Window PowerShell ISE, and ran the Get-Sysinternals function. The command and associated output are shown in the following figure.
“Now that I have gotten the Sysinternals commands installed and updated on my computer, I am out of here,” the Scripting Wife said.
“But what about…oh, never mind,” I said.
“Tata for now,” she said. And with that, she was gone.
Join me tomorrow for Episode 10 of the BATCHman series.
I invite you to follow me on Twitter and Facebook. You can also follow the Scripting Wife on Twitter If you have any questions, send email to me at email@example.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
this is way cool! A clever idea to "outsource" the real function to a file and put just a little wrapper function in your profile!
I should revise my profiles to see, if I can reduce the size of them this way!
Btw: It's very nice to have read of you and the scripting wife here ( Greetings to Teresa! ) Is it .... to be continued ... ?!?. I hope so!
But now, let's see what BATCHman will experience tomorrow.
net.exe : System error 67 has occurred.
At line:13 char:6
+ net <<<< use \\live.sysinternals.com\tools /persistent:no
+ CategoryInfo : NotSpecified: (System error 67 has occurred.:String) , RemoteException
+ FullyQualifiedErrorId : NativeCommandError
The network name cannot be found.
I keep getting this error in the Get-SysInternals function. Using XP with Powershell v2. Any thoughts?
I used a slightly alternate implementation for this.
The main difference is that I used copy-item using the UNC path rather than mapping the drive.
It is based around downloading the zipped package.
Be sure WebClient service is running.
At an administrative command prompt
NET START webclient
The WebClient service is required in order to access webfolders as a UNC path.
Thank you so much. Learn something new everyday.
SideWinder - It took me over 20 minutes to figure it out so I suspected it mugh be useful. WebFolders should be running so I am not sure why they are not on some systems.
Why does it always have to be PowerShell? Why not just "robocopy \\live.sysinternals.com\tools C:\Temp\SysInternals/E /W:1 /R:1" and get rid of the other 98.923 lines ;)