Friday, May 15, 2009

Remotely execute GPUPDATE via PowerShell with Invoke-GPUpdate function

I was looking around a few days brushing up on the new cmdlets in PowerShell v2. Today the need arose (again) where I wanted to remotely force a GPUPDATE on several computers (for updating computer components of a GPO). Of course I wanted to accomplish this with PowerShell. The first thing that came to mind was the “Start-Process” cmdlet. Unfortunately a quick look at the help for Start-Process showed no option for connecting to a remote computer. The next thing that came to mind was WMI, specifically the new Invoke-WMIMethod (with a name like “Invoke-WMIMethod”, how could it go wrong). After a quick read of the help for Invoke-WMIMethod I was off and running. A few one liner tests from the console and then I ended up with the function below.

Invoke-GPUpdate takes one parameter called “ComputerName”, which as you can guess by the name provides the name (or IP) of the computer you want to run gpupdate on. The first thing the function does is attempt to connect to WMI on the target computer (Get-WMIObject). If it fails to connect to WMI it throws an error (“Unable to connect to <computername>”). If it successfully connects to WMI then it uses the version information from win32_operatingsystem to determine how to update group policy. If the OS version is equal to 5.1 or greater then it uses gpupdate, if it is less than 5.1 then it uses secedit. After PowerShell has determined how it is going to update group policy the Invoke-WMIMethod is used create a new Windows process on the remote computer to start either gpupdate ("gpupdate /target:Computer /force") or secedit (“secedit /refreshpolicy machine_policy /enforce”).

Requires PowerShell v2



function Invoke-GPUpdate(){
param($ComputerName = ".")
$targetOSInfo = Get-WmiObject -ComputerName $ComputerName -Class Win32_OperatingSystem -ErrorAction SilentlyContinue
If ($targetOSInfo -eq $null){Write-Host -BackgroundColor Black -ForegroundColor Red "Unable to connect to $ComputerName"}
Else{
If ($targetOSInfo.version -ge 5.1){Invoke-WmiMethod -ComputerName $ComputerName -Path win32_process -Name create -ArgumentList "gpupdate /target:Computer /force /wait:0" Out-Null}
Else{Invoke-WmiMethod -ComputerName $ComputerName -Path win32_process -Name create –ArgumentList “secedit /refreshpolicy machine_policy /enforce“ Out-Null}
}
}



Example Usage

single computer:
“Invoke-GPUpdate –ComputerName computer01”

multiple computers from array:
$computerArray = “computer01”,“computer02”,“computer03”,“computer04”
$computerArray Foreach-Object{Invoke-GPUpdate -ComputerName $_}

multiple computers from a particular Active Directory OU (using Quest ActiveRoles for Active Directory):
Get-QADComputer -SearchRoot 'ou=computers,ou=locationA,dc=directory,dc=local' %{Invoke-GPUpdate -ComputerName $_.dnsname}

Wednesday, May 6, 2009

UPDATED (05/06/2009): Booting Windows 7/Server 2008 R2 from a VHD

*Updated for the RC builds (7100) of Windows 7 and Server 2008 R2

Original Post: Booting Windows 7/Server 2008 R2 from a VHD

Changes in RC

After downloading the bits for the RCs (build 7100) for Windows 7 and Server 2008 R2 I reloaded my laptop from scratch starting with Windows 7 x86 as my base OS. After 7 was up and running I followed the steps in my original post (Booting Windows 7/Server 2008 R2 from a VHD) to get Server 2008 R2 booting from VHD. There were only two differences between the beta and the RC I ran into in setting this up.

1) The first was after booting to the Server 2008 R2 media in trying to access the recovery console (I might have had this issue the in the beta and forgotten about it). After clicking on “repair your computer” it detects the Windows 7 installation and throws a error that the recovery tools are incompatible with the detected Operating System (the Windows 7 installation). At this point it didn’t allow me to proceed. The other option on this screen is to select an image to recover from. After selecting to recover from an image it searches for a supported recovery image (fails to find one). Once clicking on OK I was taken to the recovery console where I could then access the command shell and proceed.

2) The second difference I ran into was creating the VHD file. When in diskpart using the the “create vdisk” command it appears the default disk type has changed. In beta (build 7000) the default disk type was “expandable”. In RC (build 7100) the default disk type is “fixed”. From my original example I needed to change the command from “create vdisk file=’C:\VHDs\WinServ2008R2.vhd’ maximum=20480” to “create vdisk file=’C:\VHDs\WinServ2008R2.vhd’ maximum=20480 type=expandable”. While a fixed disk might slightly improve performance and keep me from over allocating space it’s not worth consuming all of the space up front.

 

bcdedit

I also realized I never discussed bcdedit.exe (Boot Configuration Data Edit). bcdedit is the tool you use to modify or remove (and manually create) entries in the Windows Boot Manager. bcdedit.exe is run from within Windows and needs Administrative rights to run (assuming you have UAC enabled make sure you launch an elevated prompt to make changes). Running bcdedit without any parameters displays the current entries and their values (example 1). Each available operating system is listed under a sections labeled “Windows Boot Loader”. To make any changes (including deleting any entry) you need to reference the unique “identifier” for that particular OS.

 

Modifying Boot Manager Entries

For each of my entries I wanted to change the text displayed at boot to include additional information about the version and boot location. For Window 7 I wanted to change the text from “Windows 7” to “Windows 7 (C: | RC, build 7100)” and for Server from “Windows Server 2008 R2” to "Windows Server 2008 R2 (C:\VHDs\WinServer2008R2.vhd | RC, build 7100)". As you can see in the output of Example 1 the OS you are currently in is referenced by a generic identifier “{current}” instead of a unique identifier.Ffor that reason the text used to change the descriptions varies slightly for the two entries:

Commands Used to Update my Descriptions
bcdedit /set "{096a20c7-3993-11de-b7cc-d1e341e28438}" description "Windows Server 2008 R2 (C:\VHDs\WinServer2008R2.vhd | RC, build 7100)"
bcdedit /set "{current}" description "Windows 7 (C: | RC, build 7100)"

 

Deleting Boot Manager Entries

Once you decide you are finished with a VHD booted OS removing it is a two step process. You delete the actual VHD (in my case “C:\VHDs\WinServer2008R2.vhd”) and delete the boot loader data. To delete the boot loader entry first run bcdedit to obtain the unique identifier. Next run “bcdedit /delete <unique identifier> /cleanup”. Specifying the cleanup parameter removes all references to the entry in addition to removing the entry from the Boot Manager table (you can get details on “/cleanup” by typing “bcdedit /delete /?”).

Example 1

PS C:\>bcdedit.exe

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume3
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {096a20ca-3993-11de-b7cc-d1e341e28438}
displayorder            {096a20c7-3993-11de-b7cc-d1e341e28438}
                        {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.exe
description             Windows 7 (C: | RC, build 7100)
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {096a20c4-3993-11de-b7cc-d1e341e28438}
recoveryenabled         Yes
osdevice                partition=C:
systemroot              \Windows
resumeobject            {096a20c2-3993-11de-b7cc-d1e341e28438}
nx                      OptIn

Windows Boot Loader
-------------------
identifier              {096a20c7-3993-11de-b7cc-d1e341e28438}
device                  vhd=[C:]\VHDs\WinServer2008R2.vhd
path                    \Windows\system32\winload.exe
description             Windows Server 2008 R2
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {096a20c8-3993-11de-b7cc-d1e341e28438}
recoveryenabled         Yes
osdevice                vhd=[C:]\VHDs\WinServer2008R2.vhd
systemroot              \Windows
resumeobject            {096a20c6-3993-11de-b7cc-d1e341e28438}
nx                      OptOut

Tuesday, May 5, 2009

Windows Disc Image Burner

Natively burn ISO images to CD/DVD in Windows 7.

  1. right click ISO file
  2. “Burn disc image”…”Burn”
     disc image burner
  3. enjoy

That’s one less third party app to maintain.

Followers