Monday 9 September 2013

SCCM 2012 Client Failed to install - ExitCode: 1603

The following script was created from much frustration with the SCCM Client not installing on workstations and servers.  Errors were all over the map, from MSI errors to 1603 in the ccmsetup.log file.
The following errors were noted:
  • "File C:\Windows\ccmsetup\MicrosoftPolicyPlatformSetup.msi installation failed. Error text: ExitCode: 1603"
  • InstallFromManifest failed 0x80070643
  • "CcmSetup failed with error code 0x80070643"

Turns out the root cause was WMI corruption, so this little batch script worked great. 

Tested on XP, Windows 7, Server 2003, Server 2003R2, Server 2008, Server 2008R2.

This is the "shotgun" approach to repairing WMI.  Do not reboot your computer immediately after running this, as the WMI is rebuilding in the background.   I manually ran the SCCM Client install about 1 minute after the batch file completed, and it completed successfully. (Yay - another 30 seconds of success!  Now on to my next task...)

Format: BATCH

Copy and paste the text into a batch file.

@echo off
sc config winmgmt start= disabled
net stop winmgmt /y
%systemdrive%
cd %windir%\system32\wbem
For /f %%s in ('dir /b *.dll') do regsvr32 /s %%s
wmiprvse /regserver
winmgmt /regserver
net start winmgmt
for /f %%s in ('dir /b *.mof *.mfl') do mofcomp %%s
exit

SCCM Client Version SCCM Collection Query (WQL)

The following is a set of SCCM 2012 queries that I use to get the SCCM client version for Systems without SP1, with SP1, and SP1 CU2.

SCCM Collection (Tested with 2012, SP1 & CU2)

Software inventory must ben enabled and running.  Instructions found here:
http://technet.microsoft.com/en-us/library/hh509028.aspx

Language: WQL

***SCCM Clients <5.00.7804.1000 (Pre SP1)

select
SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ClientVersion < "5.00.7804.1000"


***SCCM Clients =5.00.7804.1000 (with SP1)

select
SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ClientVersion = "5.00.7804.1000"

***SCCM Clients =5.00.7804.1300 (with SP1 CU2)
 select
SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,
SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.ClientVersion = "5.00.7804.1300"
 
 

Internet Explorer Version SCCM Collection Query (WQL)

The following is an SCCM 2012 query that I use to get the IE version in my environment.  This is freely available from Microsoft and other sites, but I have slightly modified them to get exactly what I need.

SCCM Collection (Tested with 2012, SP1 CU2)

Software inventory must ben enabled and running.  Instructions found here:
http://technet.microsoft.com/en-us/library/hh509028.aspx

Change the "6.%" to "7.%", "8.%" etc. to get the different versions.

Language: WQL


select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,
SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,
SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_SoftwareFile on SMS_G_System_SoftwareFile.ResourceID = SMS_R_System.ResourceId where SMS_G_System_SoftwareFile.FileName = "iexplore.exe" and SMS_G_System_SoftwareFile.FilePath like "%prog%internet%" and SMS_G_System_SoftwareFile.FileVersion like "6.%"

Tuesday 29 January 2013

Join Domain and Rename Computer with PowerShell

   Below is a script that we use to join computers to a domain.  We use this as part of a task sequence in SCCM and feed a system name into the launching of the script.  We do not restart the computer using the script though - otherwise the task sequence would fail. 

Tested with Windows 7
Type: PowerShell 3.0 << Powershell 3.0 found here:
 http://www.microsoft.com/en-us/download/details.aspx?id=34595

# Script Usage:

# <ScriptName.ps1 MyNewComputerName>

param

([Parameter(Position=0,mandatory=
$true)]

[string]$newname) # Required Parameter, script will fail without it 

# === Set the Variables ===

$domain = "Domain"          # NETBIOS name of your domain
$DNSDomain = 'domain.local' # FQDN of your domain
$domainUserroot
= 'ADUser'  # An AD user with permissions to join workstations to the domain
$domainpass = 'supersecret' # The password for the above user
$domainUser = $domain+'\'+$domainUserroot $securePass = ConvertTo-SecureString –String $domainpass -AsPlainText –force $domaincred = New-Object System.Management.Automation.PSCredential` $domainUser,$securePass
$OU = "OU=Computers-Win7,DC=domain,DC=local" # Target OU
# === Start of Commands ===
# Add the computer to the domain
Add-Computer -DomainName $dnsdomain -Credential $domaincred -OUPath $OU 

# Rename the Computer - Requires Domain Credentials
Rename-Computer -NewName $newname -DomainCredential $domaincred # Rename Computer

Restart-Computer # Reboot the Computer
A note about the password:  Due to the nature of PSH, passing credentials is rather difficult, especially if you want to encrypt them.  I found it easier to create an AD user and lock that user account down so that it is allowed to join workstations to the specific container, rather than the former.
 

Tuesday 15 January 2013

Enable/Disable AutoAdminLogon with PowerShell

     Since the company I work for is finally upgrading to Windows 7 and replacing about 1500 desktops this year, I'm working on a sequence where the system from the manufacterer comes in and detects that it can see the domain, then proceeds through several configuration tasks so that our deployment staff spend less time at each system.
Gone are the days when they had to follow a page of instructions for configuring each system.

     My first script is to enable AutoAdminLogon in the registry and give it the user and password required.

For Windows 7
Type: PowerShell  
$Regkey= "HKLM:\Software\Microsoft\Windows NT\Currentversion\WinLogon"

 
$DefaultUserName = 'Administrator'
$DefaultPassword = 'P@ssword'

# This function just gets $true or $false
function Test-RegistryValue($path, $name)
{
$key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
$key -and $null -ne $key.GetValue($name, $null)
}

# Gets the specified registry value or $null if it is missing
function Get-RegistryValue($path, $name)
{
$key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
if ($key) {$key.GetValue($name, $null)}
}

#AutoAdminLogon Value
$AALRegValExist = Test-RegistryValue $Regkey AutoAdminLogon
$AALRegVal = Get-RegistryValue $RegKey AutoAdminLogon

if ($AALRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name AutoAdminLogon -Value 1 }

elseif ($AALRegVal -ne 1) { Set-ItemProperty -Path $Regkey -Name AutoAdminLogon -Value 1 }

#DefaultUserName Value
$DUNRegValExist = Test-RegistryValue $Regkey DefaultUserName
$DUNRegVal = Get-RegistryValue $RegKey DefaultUserName

if ($DUNRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name DefaultUserName -Value $DefaultUserName }

elseif ($DUNRegVal -ne $DefaultUserName) { Set-ItemProperty -Path $Regkey -Name DefaultUserName -Value $DefaultUserName }

#DefaultPassword Value
$DPRegValExist = Test-RegistryValue $Regkey DefaultPassword
$DPRegVal = Get-RegistryValue $RegKey DefaultPassword

if ($DPRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name DefaultPassword -Value $DefaultPassword }

elseif ($DPRegVal -ne $DefaultPassword) { Set-ItemProperty -Path $Regkey -Name DefaultPassword -Value $DefaultPassword }

Give the Default Username and Password, and execute with PS. 

The reason that there is a registry value test is that powershell has two different commands for creating a new registry value (New-ItemProperty) and changing on (Set-ItemProperty)

The following script is for disabling the AutoAdminLogon.  The user and password is cleared, and the AutoAdminLogon registry value is changed to 0.

$Regkey= "HKLM:\Software\Microsoft\Windows NT\Currentversion\WinLogon"

 
$DefaultUserName = ''
$DefaultPassword = ''

# This function just gets $true or $false
function Test-RegistryValue($path, $name)
{
$key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
$key -and $null -ne $key.GetValue($name, $null)
}

# Gets the specified registry value or $null if it is missing
function Get-RegistryValue($path, $name)
{
$key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
if ($key) {$key.GetValue($name, $null)}
}

#AutoAdminLogon Value
$AALRegValExist = Test-RegistryValue $Regkey AutoAdminLogon
$AALRegVal = Get-RegistryValue $RegKey AutoAdminLogon

if ($AALRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name AutoAdminLogon -Value 0 }

elseif ($AALRegVal -ne 0) { Set-ItemProperty -Path $Regkey -Name AutoAdminLogon -Value 0 }

#DefaultUserName Value
$DUNRegValExist = Test-RegistryValue $Regkey DefaultUserName
$DUNRegVal = Get-RegistryValue $RegKey DefaultUserName

if ($DUNRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name DefaultUserName -Value $DefaultUserName }

elseif ($DUNRegVal -ne $DefaultUserName) { Set-ItemProperty -Path $Regkey -Name DefaultUserName -Value $DefaultUserName }

#DefaultPassword Value
$DPRegValExist = Test-RegistryValue $Regkey DefaultPassword
$DPRegVal = Get-RegistryValue $RegKey DefaultPassword

if ($DPRegValExist -eq $null) { New-ItemProperty -Path $Regkey -Name DefaultPassword -Value $DefaultPassword }

elseif ($DPRegVal -ne $DefaultPassword) { Set-ItemProperty -Path $Regkey -Name DefaultPassword -Value $DefaultPassword }