Expert Solutions: Advanced Event 9 of the 2010 Scripting Games


 

Bookmark and Share

(Note: These solutions were written for Advanced  Event 9 of the 2010 Scripting Games.)

 

Advanced Event 9 (Windows PowerShell)

Photo of Niklas Goude

Niklas Goude is an author, IT consultant, and trainer at Enfo Zipper in Stockholm, Sweden. Niklas has extensive experience in automating and implementing SharePoint environments using Windows PowerShell. Niklas has written a Windows PowerShell book for Swedish IT pros, and is currently co-authoring a book with Mattias Karlsson titled, PowerShell for Microsoft SharePoint 2010 Administrators, which will be published in English by McGraw-Hill later this year. Niklas runs the blog, http://www.powershell.nu, where he shares scripts, examples, and solutions for administrative tasks in Windows environments through Windows PowerShell.

The hows

The script is written in a pretty straightforward way. There’s a param at the top followed by a help function, followed by script functions, and main code at the bottom of the script. The true “magic” achieved in the script lies in the do…while loops that check if a process is running. The niceMode switch relies on the same technique. There’s also a switch included that checks which type of operating system the computer is running. Let’s walk through the do…while loops that achieve the “magic.” 

do {

    if(Get-Process | Where { $_.Path -match “\$program$” -OR $_.ProcessName -eq “$program” }) { $programStarted = $true }

  } while ($programStarted -ne $true) 

The first do…while loop checks if a given program (executable file or process name ) is running on the computer, and, if not, waits until the program is started. The loop continues as long as the given program is not started. When the program is started on the computer, the script continues:

  if($niceMode) {

    do {

      if(Get-Process | Where { $_.ProcessName -eq “WINWORD” -OR $_.ProcessName -eq “EXCEL” }){

        “Excel or Word”

        Start-Sleep -Seconds 300

      } else {

        $ExcelOrWord = $true

      }

    } while ($ExcelOrWord -ne $true)

  }

The second do…while loop checks if niceMode is active, and if niceMode is active, the script checks if Microsoft Word or Excel is running on the computer. If either of the Office programs is running, the script waits for five minutes and checks again to see if either Word or Excel is running on the computer. As soon as they are not running, the script continues.

  switch((get-wmiobject Win32_OperatingSystem).BuildNumber) {

    { $_ -eq 2600 }{ funXP }

    { $_ -eq 6000 } { funVista }

    { $_ -eq 7600 } { funWin7 }

    Default { funOther }

  } 

The script then checks which type of operating system that is installed on the computer. The script supports three operating systems: Windows 7, Windows Vista, and Windows XP. All other operating systems are classified as “other.” Depending on the operating system, different functions are executed. The functions display different graphics for the user: Windows 7 uses the Windows Presentation Foundation, Windows Vista displays a form, and Windows XP uses Merlin. Other operating systems use the Write-Progress cmdlet to display the progress.

Here are four screen shots displaying the different operating systems:

 

 

 


After the graphics are displayed, the current logged-on user is logged off through WMI:

(gwmi win32_operatingsystem).Win32Shutdown(4) | Out-Null

The number 4 is used to force a logoff. The command is then piped to the Out-Null cmdlet.

The whys

The script’s main focus is on the different ways of presenting the graphics. The script includes the Microsoft Agent, Windows Forms, Windows Presentation Foundation, and the Write-Progress cmdlet included in Windows PowerShell 2.0. I think that combining different technologies such as WMI, COM, and the .NET Framework in a script shows the benefits of using Windows PowerShell to automate your environments.

The special stuff

The functions included in the script show the different approaches you can take to handle different operating systems through Windows PowerShell. The Microsoft Agent doesn’t work as well on Windows 7 or Windows Vista as it does on Windows XP and the Windows Presentation Foundation is better suited for newer operating systems. You can handle this in a simple and fun way using Windows PowerShell.

The full script is shown here:

param([string]$program, [switch]$niceMode, [switch]$help)

 

function funhelp {

 

  #################################################################

  #

  # A Help function explaining how to use the script

  #

  #################################################################

$HelpText = @”

 

DESCRIPTION:

NAME: AEvent9

 

Checks if a program is started and logs off current user

 

PARAMETERS:

-program    program executable or processname

-niceMode   Checks if Microsoft Word or Excel is active and waits until

            Microsoft Word or Excel is shut down. A check is done

            every 5 minutes.

-help       diplays the help text.        

SYNTAX:

 

.AEvent9.ps1 -program calc.exe

 

Waits until calc.exe is started. When calc.exe is started, the current user will be prompted with a countdown and logged off within 60 seconds.

.AEvent9.ps1 -program calc -niceMode

 

Waits until calc.exe is started. When calc.exe is started, the script checks if Microsoft Word or Excel is active and waits until the programs are shut down.

The user will then be prompted with a countdown and logged off within 60 seconds.

 

.AEvent9.ps1 -program calc -help

 

Displays the help topic for the script

 

“@

$HelpText

 

}

 

function funXP {

 

  #################################################################

  #

  # Rely on Merlin to do the job

  #

  #################################################################

 

$GetAgent = new-object -com Agent.Control.2

  $GetAgent.Connected = 1

  [void]$GetAgent.Characters.Load(“Merlin”)

  $Agent = $GetAgent.Characters.Character(“Merlin”)

  [void]$Agent.Show()

 

  for($CountDown = 60; $CountDown -ge 0; $CountDown–) {

    $speak = $Agent.Speak(“Logoff in: $CountDown seconds”)

    do {

      #Wait for Speak.status to equal 1

    } while ($speak.status -ne 1)

  }

}

 

function funVista {

 

  #################################################################

Comments (0)