Installing Roxio Creator Starter Silently

Don’t you hate those apps that stubbornly refuse to install when using SCCM?  For me, one such app was Roxio Creator Starter.  The install switches do not seem to be well documented.  After googling, I found the following command line which works:

setup.exe RX_EULA_ACCEPTED=1 /qn ADDLOCAL=ALL Reboot=ReallySuppress

But when deploying it to an x64 OS using SCCM, it fails to install.  So I opened the ‘AppEnforce.log’ on the client and found an exit code of 1622.  Using the Error Lookup tool in the CMTrace utility (Tools > Error Lookup), the following description is given:

“Error opening installation log file. Verify that the specified log file location exists and that you can write to it.”

It seems like some apps want to log to a location in the user profile area, which it can’t really do when installing in the SYSTEM context, so I added a switch to log to the %TEMP% location, which will be C:\Windows\Temp.  Now it installs fine using SCCM 🙂

setup.exe RX_EULA_ACCEPTED=1 /qn ADDLOCAL=ALL Reboot=ReallySuppress /l*v “%TEMP%\Roxio.log”

Prompting for Input During a Task Sequence

Sometimes when running an SCCM task sequence, you want to prompt for input, for example to populate a Task Sequence variable that you will use later.  In this example, I am encrypting a laptop HDD (SED) using Wave ERAS, and I’m using a command-line tool that populates the pre-boot authentication screen with the AD account of the laptop end-user. This runs during a post-deployment task sequence that provisions the encryption.   As each laptop is prepared for a different end user, I needed to prompt for the user account during the task sequence, then pass the input to a script that adds the account to the encryption pre-boot.

To accomplish this I decided to use a Powershell script with ServiceUI.exe to prompt for and set the TS variable, then pass this variable to the encryption script as a parameter.  I tested it using SCCM 2012R2 integrated with MDT2013, but I can’t see why it wouldn’t work in older versions that support ServiceUI.exe.

Here’s the ‘how to’:

Create a Package

First, create a package in SCCM that contains the Powershell script below, and the ServiceUI.exe.  ServiceUI.exe comes with MDT and allows you to break out of the TS session into the user session, where you can interact.  Since I still deploy some x86 OS’s at times, I decided to include both the x86 and x64 version of the executable in the same package, and rename them accordingly, although the x86 version will probably work for both architectures.  Then I use a TS condition to create separate steps for x86 and x64.

package

You can find the ServiceUI.exe here:

C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64, or
C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x86

PromptForUsername.ps1

<#
PromptForUsername v1
-----------------
This script prompts for input during a task sequence, and sets the input as a TS variable.
#>

# Close the TS UI temporarily
$TSProgressUI = New-Object -COMObject Microsoft.SMS.TSProgressUI
$TSProgressUI.CloseProgressDialog()

# Prompt for input
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$TSUsername = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the username of the end user", "Username prompt", "eg tjones")

# Set the TS variable
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$tsenv.Value("TSUsername") = $TSUsername

Distribute your package to your DPs, no program is required for it.

What does the script do?

First, it hides the task sequence UI while the prompt is displayed, otherwise it will appear behind the UI.  Second, we prompt for the input.  Lastly we pass the input into a new TS variable called %TSUsername%.

Add Task Sequence Steps

Next, we will add a step to the task sequence that prompts for the username.  Add a ‘Run Command Line’ step and use the package you created.  Call the ServiceUI_x86.exe with the following parameters:

ServiceUI_x86.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File PromptForUsername.ps1

TS1

Do the same for the x64 version of ServiceUI, if you are using both versions.  You can set a simple OS version condition on each task to determine the architecture:

TS2

Next I update my ‘add user’ step passing the %TSUsername% variable into the parameters of the command:

TS3

The result

When the task sequence runs, it will prompt for the username:

TS Prompt

It then adds the user into the preboot authentication via the script.  We can see from the SMSTS.log that it correctly substitutes the variable when running the command:

log1

This example uses a non-deployment task sequence; it should also work during a deployment, although I didn’t test it yet 🙂  To work during the WinPE phase, you will need to add Powershell support to your boot image.  For OS deployment there are more elegant ways of getting input during the WinPE Phase, such as Jason Sandys’ OSD++, or by using an HTA, but that may seem a bit much if just one or two inputs are required, so this is an excellent and easily implemented alternative that can be used during any task sequence.

More info:

http://social.technet.microsoft.com/Forums/systemcenter/en-US/22118e37-1a66-43cd-a1e4-12b50de0ee5c/powershell-script-needs-to-display-message-box-to-user
http://www.scconfigmgr.com/2013/10/02/prompt-for-computer-name-during-osd-with-powershell/
http://blogs.technet.com/b/mniehaus/archive/2009/09/22/running-powershell-scripts-as-part-of-a-task-sequence.aspx
http://www.vroege.biz/?p=417

Creating SCCM2012 Packages with Powershell

This simple powershell script will create a package in SCCM2012 with a single standard program, and distribute it to your DP Group.  It uses the ConfigMgr native commands, and you can add/remove/change the parameters to customise the script for your own environment.

It does not create a deployment, but that’s easy enough to do, just add code like the following after the content distribution part:

Write-Host 'Deploying Application to Collection'
$Deployment = Start-CMPackageDeployment `
 -CollectionName MyCollection `
 -PackageName $Pkg `
 -StandardProgramName $Pkg `
 -DeployPurpose Required

Create Package

<#
-------------
CreatePackage v1
-------------

This script creates and distributes an SCCM2012 package with a single standard program

Tested on: SCCM2012R2

//Instructions//

Set the variables below as required
#>


###############
## Variables ##
###############

# ConfigMgr Site Code
   $SiteCode = "ABC"
# Name of the package
   $Pkg = "7zip"
# Location of Source files
   $Source = "\\MySCCMServer\PackageSource\7Zip"
# Installation command line
   $CommandLine = "setup.exe -s"
# Required amount of disk space
   $DiskSpace = "200"
# Units for Disk space requirement, eg KB, MB or GB
   $DiskUnit = "MB"
# Maximum allowed run time
   $Duration = "16"
# Program can run, eg "WhetherOrNotUserIsLoggedOn", "OnlyWhenNoUserIsLoggedOn", "OnlyWhenUserIsLoggedOn"
   $RunType = "WhetherOrNotUserIsLoggedOn"
# Run mode, eg "RunWithAdministrativeRights" or "RunWithUserRights"
   $RunMode = "RunWithAdministrativeRights"
# Allow user to interact?
   $UserInteraction = $False
# Allow program to be installed from task sequence?
   $EnableTS = $True
# Distribution Point Group to distribute content to
   $DPG = "All Distribution Points"


# Import ConfigMgr Module

Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
$Drive = $SiteCode + ':'
cd $Drive
cls
$ErrorActionPreference = "Inquire"


## Create the Package ##

write-host 'Creating Package'
$Package = New-CMPackage -Name $Pkg -Path $Source


## Create a Program

write-host 'Adding Program'
$Program = New-CMProgram `
 -PackageName $Pkg `
 -StandardProgramName $Pkg `
 -CommandLine $CommandLine `
 -DiskSpaceRequirement $DiskSpace `
 -DiskSpaceUnit $DiskUnit `
 -Duration $Duration `
 -ProgramRunType $RunType `
 -RunMode $RunMode `
 -UserInteraction $UserInteraction


## Update Program

write-host 'Updating Program'
$ProgramUpdate = Set-CMProgram `
 -Name $Pkg `
 -StandardProgramName $Pkg `
 -EnableTaskSequence $EnableTS


## Distribute Content to DPs ##

write-host 'Distributing Content to DPs'
Start-CMContentDistribution -PackageName $Pkg -DistributionPointGroupName $DPG

write-host 'Done!' -ForegroundColor Yellow

Installing Drivers with Standalone Media Deployments

Using SCCM standalone media can be a good way to deploy an OS when you have, for example, remote offices with no local distribution point.  However, if you use DVD media it can result in several DVDs if you include all the applications and drivers.  So I prefer to install the drivers and applications separately after deployment and keep the OS install on one or two DVDs. As we use Dell computers, it’s quite easy to get hold of the driver pack from the Dell website, which you can then install using PnPUnattend.  To speed up the process, I wrote a simple batch script that will download the relevant driver pack from Dell and install it.

This process can also be used for non-Dell models, you simply download the drivers you need, extract them, place them in the C:\Drivers folder, add the registry key, and run the PnPUnattend command.

Note: You need to have at least a NIC driver installed before running the script, so you can connect to the internet.

@echo off
cls
:Start
echo *********************************
echo Download and Install Dell Drivers
echo *********************************
echo _
echo 1. E4200
echo 2. E6220
echo 3. E6320
echo 4. E6410
echo 5. E6420
echo 6. E6430
echo 7. E6430s
echo 8. E6530
echo 9. Optiplex 9010
echo 10. Optiplex 9020
echo 11. Precision T5500
echo 12. E7240
echo 13. E7440
echo 14. E6440
echo 15. E6540
echo 16. E6230
echo 17. E6520
echo 18. Optiplex 990
echo _
set /p choice=Which Model do you wish to install Drivers for?
if '%choice%'=='1' goto E4200
if '%choice%'=='2' goto E6220
if '%choice%'=='3' goto E6320
if '%choice%'=='4' goto E6410
if '%choice%'=='5' goto E6420
if '%choice%'=='6' goto E6430
if '%choice%'=='7' goto E6430s
if '%choice%'=='8' goto E6530
if '%choice%'=='9' goto 9010
if '%choice%'=='10' goto 9020
if '%choice%'=='11' goto T5500
if '%choice%'=='12' goto E7240
if '%choice%'=='13' goto E7440
if '%choice%'=='14' goto E6440
if '%choice%'=='15' goto E6540
if '%choice%'=='16' goto E6230
if '%choice%'=='17' goto E6520
if '%choice%'=='18' goto 990
cls
echo !! "%choice%" is not a valid choice! Please try again"!
echo _
goto Start

mkdir C:\DriverPacks
mkdir C:\Drivers

:E4200

echo Downloading Driver cab from Dell for E4200...
echo _
start /wait bitsadmin /transfer E4200Drivers /download /priority normal http://downloads.dell.com/FOLDER00680122M/1/E4200-win7-A03-M90D4.CAB C:\DriverPacks\E4200-win7-A03-M90D4.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E4200-win7-A03-M90D4.CAB -f:* C:\Drivers
goto Install_Drivers

:E6220

echo Downloading Driver cab from Dell for E6220...
echo _
start /wait bitsadmin /transfer E6220Drivers /download /priority normal http://downloads.dell.com/FOLDER01449232M/1/E6220-win7-A08-0VK93.CAB C:\DriverPacks\E6220-win7-A08-0VK93.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6220-win7-A08-0VK93.CAB -f:* C:\Drivers
goto Install_Drivers

:E6320

echo Downloading Driver cab from Dell for E6320...
echo _
start /wait bitsadmin /transfer E6320Drivers /download /priority normal http://downloads.dell.com/FOLDER01440819M/1/E6320-win7-A10-2H76N.CAB C:\DriverPacks\E6320-win7-A10-2H76N.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6320-win7-A10-2H76N.CAB -f:* C:\Drivers
goto Install_Drivers

:E6410

echo Downloading Driver cab from Dell for E6410...
echo _
start /wait bitsadmin /transfer E6410Drivers /download /priority normal http://downloads.dell.com/FOLDER01384339M/1/E6410-win7-A11-D2H6P.CAB C:\DriverPacks\E6410-win7-A11-D2H6P.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6410-win7-A11-D2H6P.CAB -f:* C:\Drivers
goto Install_Drivers

:E6420

echo Downloading Driver cab from Dell for E6420...
echo _
start /wait bitsadmin /transfer E6420Drivers /download /priority normal http://downloads.dell.com/FOLDER01440751M/1/E6420-win7-A10-KFNW7.CAB C:\DriverPacks\E6420-win7-A10-KFNW7.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6420-win7-A10-KFNW7.CAB -f:* C:\Drivers
goto Install_Drivers

:E6430

echo Downloading Driver cab from Dell for E6430...
echo _
start /wait bitsadmin /transfer E6430Drivers /download /priority normal http://downloads.dell.com/FOLDER01659570M/1/E6430-win7-A07-KGR03.CAB C:\DriverPacks\E6430-win7-A07-KGR03.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6430-win7-A07-KGR03.CAB -f:* C:\Drivers
goto Install_Drivers

:E6430s

echo Downloading Driver cab from Dell for E6430s...
echo _
start /wait bitsadmin /transfer E6430SDrivers /download /priority normal http://downloads.dell.com/FOLDER01675322M/1/E6430s-win7-A05-GY4MD.CAB C:\DriverPacks\E6430s-win7-A05-GY4MD.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6430s-win7-A05-GY4MD.CAB -f:* C:\Drivers
goto Install_Drivers

:E6530

echo Downloading Driver cab from Dell for E6530...
echo _
start /wait bitsadmin /transfer E6530Drivers /download /priority normal http://downloads.dell.com/FOLDER01658654M/1/E6530-win7-A08-MK7V1.CAB C:\DriverPacks\E6530-win7-A08-MK7V1.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6530-win7-A08-MK7V1.CAB -f:* C:\Drivers
goto Install_Drivers

:9010

echo Downloading Driver cab from Dell for Optiplex 9010...
echo _
start /wait bitsadmin /transfer 9010Drivers /download /priority normal http://downloads.dell.com/FOLDER01566211M/1/9010-win7-A05-X8DTY.CAB C:\DriverPacks\9010-win7-A05-X8DTY.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\9010-win7-A05-X8DTY.CAB -f:* C:\Drivers
goto Install_Drivers

:9020

echo Downloading Driver cab from Dell for Optiplex 9020...
echo _
start /wait bitsadmin /transfer 9020Drivers /download /priority normal http://downloads.dell.com/FOLDER01764360M/1/9020-win7-A01-4CG9T.CAB C:\DriverPacks\9020-win7-A01-4CG9T.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\9020-win7-A01-4CG9T.CAB -f:* C:\Drivers
goto Install_Drivers

:T5500

echo Downloading Driver cab from Dell for T5500...
echo _
start /wait bitsadmin /transfer T5500Drivers /download /priority normal http://downloads.dell.com/sysman/T5500-Win7-A00-R253041.CAB C:\DriverPacks\T5500-Win7-A00-R253041.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\T5500-Win7-A00-R253041.CAB -f:* C:\Drivers
goto Install_Drivers

:E7240

echo Downloading Driver cab from Dell for E7240...
echo _
start /wait bitsadmin /transfer E7240Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01819337M/1/E7240-win7-A01-XK9P3.CAB C:\DriverPacks\E7240-win7-A01-XK9P3.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E7240-win7-A01-XK9P3.CAB -f:* C:\Drivers
goto Install_Drivers

:E7440

echo Downloading Driver cab from Dell for E7440...
echo _
start /wait bitsadmin /transfer E7440Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01819350M/1/E7440-win7-A01-XT5VG.CAB C:\DriverPacks\E7440-win7-A01-XT5VG.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E7440-win7-A01-XT5VG.CAB -f:* C:\Drivers
goto Install_Drivers

:E6440

echo Downloading Driver cab from Dell for E6440...
echo _
start /wait bitsadmin /transfer E6440Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01832732M/1/E6440-win7-A01-5DDKN.CAB C:\DriverPacks\E6440-win7-A01-5DDKN.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6440-win7-A01-5DDKN.CAB -f:* C:\Drivers
goto Install_Drivers

:E6540

echo Downloading Driver cab from Dell for E6540...
echo _
start /wait bitsadmin /transfer E6540Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01832723M/1/E6540-win7-A02-JF7Y8.CAB C:\DriverPacks\E6540-win7-A02-JF7Y8.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6540-win7-A02-JF7Y8.CAB -f:* C:\Drivers
goto Install_Drivers

:E6230

echo Downloading Driver cab from Dell for E6230...
echo _
start /wait bitsadmin /transfer E6230Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01692655M/1/E6230-win7-A05-7D8JC.CAB C:\DriverPacks\E6230-win7-A05-7D8JC.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6230-win7-A05-7D8JC.CAB -f:* C:\Drivers
goto Install_Drivers

:E6520

echo Downloading Driver cab from Dell for E6520...
echo _
start /wait bitsadmin /transfer E6520Drivers /download /priority normal http://downloads-us.dell.com/FOLDER01819787M/1/E6520-win7-A10-P2X6K.CAB C:\DriverPacks\E6520-win7-A10-P2X6K.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\E6520-win7-A10-P2X6K.CAB -f:* C:\Drivers
goto Install_Drivers

:990

echo Downloading Driver cab from Dell for Optiplex 990...
echo _
start /wait bitsadmin /transfer 990Drivers /download /priority normal http://downloads.dell.com/FOLDER01834164M/1/990-win7-A09-6DHG2.CAB C:\DriverPacks\990-win7-A09-6DHG2.CAB
echo _
echo Expanding Cab file...
echo _
start /wait expand C:\DriverPacks\990-win7-A09-6DHG2.CAB -f:* C:\Drivers
goto Install_Drivers

:Install_Drivers

echo _
echo Configuring Registry..
echo _
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UnattendSettings\PnPUnattend\DriverPaths\1" /v Path /t REG_SZ /d "C:\Drivers"
echo _
Echo Initiating PNP driver installation...
echo _
start /wait C:\Windows\System32\pnpunattend.exe auditsystem /l
goto End
:End

rmdir C:\DriverPacks /S /Q
rmdir C:\Drivers /S /Q

pause

Re-running a Task Sequence

What happens if your SCCM task sequence fails?  Well you troubleshoot it, fix the problem, and rerun it.  Easy to do if the task sequence is an ‘available’ deployment.  You just refresh the machine policy on the computer, go the Software Center, or Run Advertised Programs, and run it again.   And if your task sequence rerun behaviour is set to ‘Rerun if failed previous attempt’ it will run again anyway.

But what if it’s a required deployment?  There seems to be no easy ‘out-of-the-box’ way to manually rerun a task sequence.  Powershell to the rescue!

This little script will rerun the task sequence by connecting to the remote machine, deleting the TS schedule from WMI, and restarting the SMS Agent Host service.  After a few seconds, the TS will run again.

You need the Task Sequence Package ID, which you can get easily from the SCCM Console, and you should have Powershell remoting configured in your environment.  You can of course run the script on a local machine by removing the ‘PSSession’ commands.

<#
ReRunTaskSequence v1
-----------------

This script reruns a task sequence on a remote computer.

Tested on: SCCM2012R2

-Prereqs:-
> You need the PackageID of the Task Sequence which you can get from the SCCM Console
> Powershell remoting must be permitted on the remote computer
> You should have local admin rights on the remote computer to restart the ccmexec service
> Variables, enter the $ComputerName and $TSID (PackageID) variables
#>

# Enter remote computername
$ComputerName = "remotecomputer"

# Start a remote PSSession
$s = New-PSSession -ComputerName $ComputerName

# Main script
Invoke-Command -Session $s -ScriptBlock `
{
$TSID = "SMS000B1"
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | ft ScheduleID # Outputs the Schedule ID
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | Remove-WmiObject # Deletes the Schedule
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | ft ScheduleID # No output confirms the deletion
Get-Service | where {$_.Name -eq "CCMExec"} | Restart-Service # Restart the SMS Agent Host service
}
Remove-PSSession $s

More info:

http://www.scconfigmgr.com/2012/11/21/re-run-task-sequence-with-powershell/
http://blogs.msdn.com/b/steverac/archive/2009/11/06/sccm-forcing-a-task-sequence-to-rerun.aspx

Installing Intel Rapid Storage Technology During a Task Sequence

With our SCCM OS deployments, I like to install some of the ‘driver apps’ that come with our Dell machines, such as the Intel Management Engine Components (AMT), Bluetooth, and Rapid Storage Technology.  But for a long time the Rapid Storage Technology always bugged me because I couldn’t install it during a task sequence, either during deployment or after.  It would give some ‘fatal error during installation’ message that wasn’t very helpful.  Since it wasn’t critical to include it, I didn’t investigate too much further, but with the new Dell 7000 series laptops, it’s a requirement to install the Intel RST version 12.8 in order for the encryption software we use to work.  So I decided to dig around a bit to get this working.

I used the ServiceUI tool from MDT to create an interactive installation during a task sequence, and then I discovered it was trying to log to a folder in the user profile area, which it couldn’t do for some reason, even though it could when installing outside of a task sequence.

It turns out there is a simple fix, and I can’t believe I didn’t think of it earlier!  I extracted the SetupRST.exe file using 7Zip, and inside were 2 msi files, one each for x86 and x64.  These can be deployed successfully during a task sequence using the standard unattended program that SCCM creates for MSI packages.

extracted

It does however force a reboot, because it updates the storage controller driver, so if you don’t want that to happen during the task sequence, be sure to add the ‘REBOOT=ReallySuppress’ switch to the msiexec command, eg:

msiexec.exe /q ALLUSERS=2 /m MSIDTJBS /i “RST_x64.msi” REBOOT=ReallySuppress

Problem solved 🙂