64-bit script execution in SCCM

Pushing out scripts with SCCM can, depending on your environment, be a bit of a hassle. Even if the script runs perfectly from the cmd/powershell console on all the target computer it’s not a guarantee it will run smoothly when distributing the script through SCCM.

Problem

We’re trying to install Type 1 Format fonts with the following non-signed powershell script named “Install.ps1”:

$sa = New-Object -ComObject Shell.Application
$pathFonts = "$(Get-Location)\Fonts"
$pathDest = "$env:windir\Fonts"
$folder = $sa.Namespace($pathFonts)
$fonts = Get-ChildItem $pathFonts *.PFM

foreach ($font in $fonts) {
	$testpath = "$pathDest\$($font.Name)"
	if ((Test-Path $testpath) -eq $false) {
		Write-Output "Installing font: $($font.Name)"
		$folder.ParseName($($font.Name)).InvokeVerb("Install")
	}
}

In short the script will scan a folder for .PFM files and do a Right-Click -> Install action on the object. This script is called from a Package/Program with the following command line:

powershell.exe -executionpolicy bypass -file .\Install.ps1

When testing this script we notice that it’s installing the fonts on Windows 7 x86 but it’s not working properly on Windows 7 x64. When looking deeper into what the script is doing on Windows 7 x64 we notice the following:

  • Script output tells that the fonts install successfully
  • We’re unable to locate fonts under C:\Windows\Fonts
  • Font files are located under C:\Windows\Fonts when using dir
  • Registry values are located under the Wow6432Node

Solution

The SCCM programs are per default started from a 32-bit command-line. To get around this problem we need to run the script in a 64-bit environment. What we’re essentially doing to work around this problem is starting the 64-bit executable from the 32-bit command line. Since the powershell.exe is located under the System32 folder we’ll have to use the sysnative folder.

What we end up doing is creating two different programs, one for 32-bit and one for 64-bit installations.
32-bit command line:

powershell.exe -executionpolicy bypass -file.\Install.ps1

64-bit command line:

%windir%\sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -file .\Install.ps1

In the SCCM console this would look something like this:

sccmconsole

Notes

This script could be easily packaged according to the new application model in SCCM 2012. Doing this would require two deployment types, one for 32-bit systems and one for 64-bit systems. Requirements will need to be configured to achieve this. Each deployment type would use the same command lines as used earlier, but would have to be complemented with detection rules which could be pointed at:

  1. C:\Windows\Fonts\<filename>
  2. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts\<keys>

The technique using sysnative could also be used to run 64-bit cmd.exe with the following command line:

%windir%\sysnative\cmd.exe

When testing new script deployments with SCCM you should always log the output. This is easily achieved by attaching the output parameter, for example:

powershell.exe -file .\Install.ps1 &gt; %temp%\FontInstaller.log
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s