Friday the 13 Script Blocks

In celebration of Friday the 13th and to help ward off any triskaidekaphobia I thought I’d offer up 13 PowerShell scriptblocks. These are scriptblocks that might solve a legitimate business need like finding how long a server has been running to the more mercurial such as how many hours before I can go home.

A scriptblock is any small piece of PowerShell code enclosed in a set of curly braces. I say small, but there’s really no limit. You can even pass parameters to a script block. In this way they are like functions but without the function key word. Save the script block to a variable and when you want to execute, use the invoke operator, the & character. For example, here’s one of my luck 13 script blocks.

#1. Get running services
$running={Param ([string]$computername=$env:computername) get-service -computername $computername |
where {$_.status -eq "Running"}}

To invoke it:

PS C:\> &$running

Because this particular script block takes a computername as a parameter I could also do this:

PS C:\> &$running Server01

I won’t post the complete script here, but these are the goodies:
#1. Get running services
#2. Get logical disk information
#3. Get day of the year
#4. Get top services by workingset size
#5. Get OS information
#6. Get system uptime
#7. get a random number between 1 and 13
#8. How old are you?
#9. get %TEMP% folder stats
#10. Get event log information
#11. Get local admin password age in days
#12. Get cmdlet summary
#13. How much time before I can go home?

I wrote many of the script blocks so that you could use them in your own functions and scripting and tried to make them re-usable as possible. They have no error handling and assume you have all the necessary permissions. Think of them as quick and dirty PowerShell snippets. The script file is simply defines the 13 script blocks. After each one is a commented example of how you might run it.

Again, I’m not promising anything life-changing but I hope you’ll have fun with them today. Download the script file 13ScriptBlocks.ps1.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

Posted in PowerShell v2.0, Scripting, WMI, Windows 7, Windows Server | Tagged , , , , , , | 2 Comments

Module Mania

More and more, you’re seeing members of the Windows PowerShell community package their contributions into modules, myself included. Although you’ll probably still see a lot of individual functions because it is often easier to demonstrate or educate. I received a comment on my Weather module that I thought merited a complete post, since I expect there are many administrators still new enough to PowerShell and especially PowerShell 2.0. The question is basically, “I’ve downloaded a module. Now what?”

One major benefit of a module over snapins, is that modules can be deployed with a simple file copy. There is no installation, registration, or the like. Extract the files and PowerShell can use them. But where? Windows PowerShell 2.0 will examine a system environmental variable called %PSMODULEPATH%

C:\Users\Jeff\>echo %psmodulepath%
C:\Windows\system32\WindowsPowerShell\v1.0\Modules\

The path you see here is for modules that would apply to any user of this computer. Open a PowerShell prompt and look at the variable and you will also see a path that is set for the current user.

PS C:\> $env:psmodulepath
C:\Users\Jeff\Documents\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\

The Modules directory does not exist by default, nor does WindowsPowerShell for that matter, so you might need to create them. Underneath the Modules directory you will have a folder for each module. Thus, you would extract my weather module to a folder called JH-Weather. In that folder are all the module files.

For the most part, these should be the only paths you need. But if you would like to specify an additional module path, you can modify the environmental variable by appending a new path.

PS C:\> $env:psmodulepath=$env:psmodulepath + ";c:\scripts"
PS C:\> $env:psmodulepath.split(";")
C:\Users\Jeff\Documents\WindowsPowerShell\Modules
C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
c:\scripts

Now, PowerShell will also search C:\Scripts for any modules.  HOWEVER..this modification is only for the current PowerShell session. If I open a new PowerShell session, I’ll be back to the same path. If you always need this path, then add the modification command to your PowerShell profile script. Make sure you make the change in your profile before you attempt to import any modules from the new folder.

The Get-Module cmdlet will show all currently loaded modules. If you want to see all the available modules use the -ListAvailable parameter.

PS C:\> Get-Module -ListAvailable | Sort Name | Select Name

Name
----
ActiveDirectory
AdminConsole
AppLocker
BitsTransfer
BSonPosh
DnsShell
DotNet
FileSystem
Godot7
GPAnswers
GroupPolicy
IsePack
JDHTools
JH-Weather
JH-WindowsUpdate
LocalUsersGroups
PowerShellPack
PSCodeGen
Pscx
PSDiagnostics
PSImageTools
PSRSS
PSSystemTools
PSUserTools
scripts
ShowTree
TaskScheduler
TroubleshootingPack
WebAdministration
WPK

When I want to use a module I import it into my session.

PS C:\> Import-Module WebAdministration

Use Get-Command to see the module contents.

Creating modules is a completely different topic for another day, but I hope this has helped get you started in the right direction regarding what to do with modules. If not, let me know. There is also a help topic, About_Modules you should read. Don Jones and I also cover modules in Windows PowerShell 2.0: TFM

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

Posted in PowerShell v2.0, SAPIEN Press | Tagged , , , | 6 Comments

Windows Update Module

I don’t have a large environment to manage, but I do have a number of test boxes I try to keep up date using Windows Software Update Server (WSUS). Occasionally I’ve needed to manage things client-side. Unfortunately, there aren’t a lot of good tools, and nothing PowerShell-related that I’ve found so I wrote my own. At the end of this post you’ll be able to download a zip file with a self-extracting exe file to install my Windows Update module. Once installed, open an elevated PowerShell session and import the JH-WindowsUpdate module.

The module consists of the following commands:

  • Get-WindowsUpdateLog
  • Backup-WindowsUpdateLog
  • Clear-WindowsUpdateLog
  • Get-WindowsUpdate
  • Install-WindowsUpdate

The first challenge I tackled was finding an easier way to work with the client side event log. This text file, WindowsUpdate.log can get quite unwieldy very quickly. What I wanted was an object-based solution so I could find information. Get-WindowsUpdateLog takes the current log and turns each line into an object. Any lines that are just comment characters are stripped out.  You end up with an object like this.

Component    : Report
Message      : Reporter successfully uploaded 2 events.
PID          : 1100
Computername : SERENITY
TID          : 17c0
Category     : Normal
Datetime     : 8/3/2010 7:47:26 AM

The function can also query remote computers and has a parameter to run as a job, which I typically do because processing the log file can take some time. I typically use it like this:

PS C:\> $wu=Get-WindowsUpdatelog
PS C:\> $wu | select DateTime,Component,Category,Message

When the file gets too big or whenever you feel like it, you can clear the log using Clear-WindowsUpdateLog. This will require restarting the WUAUSERV service. You can manage remote computers as well via WinRM. But you might want to first make a backup copy with Backup-WindowsUpdateLog. Be sure to look at command help and examples for everything.

The next part of the puzzle are the updates themselves. Fortunately there is a COM object that can be used to find and download Windows Updates.

#create session objects
$updateSession = New-Object -ComObject "Microsoft.Update.Session"
$updateSearcher = $updateSession.CreateUpdateSearcher()

The Get-WindowsUpdate command will find all recommended updates needed on the local computer. Or you can use -All.

get-windowsupdate screen shotThe command doesn’t directly support remote computers, but you should be able to run it in a remote session. Installing updates uses almost the same approach with Install-WindowsUpdate. The default is to install Critical updates only. But you can install by severity, title or all.

Install-WindowsUpdate screenshotIf the update requires a reboot, the computer will not automatically reboot unless you specify -Reboot.

Unfortunately, installing updates must be done locally in an interactive session. There is a well known bug with this COM object that nobody has yet to find a way to beat. The best thing you can do for remote computers is to use SCHTASKS.EXE and remotely create a scheduled task to run the function on the remote computer. Of course you need to copy the module to the remote computer or at least load the function.

Please find a way to test all of this in a non-production environment. You can download the zip file with the self-extracting exe file here. Please post any followups, bugs or comments to this post.

Finally, and I’m trying something new here, but if you feel this module (or anything I’ve ever published for that matter)  is of value to you or your organization, I hope you’ll consider adding something to my Paypal tip jar. Any contribution would be appreciated and allows me to continue developing solutions like this along with all my other PowerShell endeavors. Thank you.

UPDATE: I’ve already made an update. I’ve tweaked a few of the functions to fix a few bugs and hopefully improve performance. The original zip file with the self-extracting archive has been update. However, for people with mapped home drives the default install path will be a problem. You can always manually specify where to install per user, but anyone just clicking through will run into problems.  Therefore, I’ve also created a simple zip file which you can download here. Manually extract the contents to a folder in your PSModulePath which you can check by looking at $env:PSModulePath.

Post to Twitter Post to Delicious Post to Facebook Post to StumbleUpon

Posted in PowerShell v2.0, Scripting, Windows 7, Windows Server | Tagged , , , , , | 3 Comments