Install SCCM application using base variable

The dynamic part of this is really simple and can be made into really complex installation sequences. Here I will only showcase the simplest of ways to use it.

So we are talking about installation that uses base variable. This an be used in many ways

You can write them with powershell to your computer as you go. Meaning that you have some kind of SQL query to search something and based on results you write them into variables to that computer being installed. Or query AD group based variables of premade computer account or what ever. Its not really limited on ways how to use it.

So lets play with the idea for a sec.

So here we have a multiple collection that have a variable placed upon the collection. If your computer is a member of this group then it will get the app01 variable that guides installation to

With app variable you need to have the variables placed in a right order. So if you have app01 and app03 being deployed, you will only install app01. You have to play around the problem by re-writing the computer variables so you will get app01 and app02. There are examples of this in the internet.

For example David O’Brian wrote this post about the matter, please check it out:
ConfigMgr – Application Base variables the easy way with Powershell – Cloud for the win!

Behind the link you may have an example script on how to rename variables.

Based upon David O’Brian’s script there is a variable named APP used in the example script. And It uses App_Variables.log filename to log events.


if ($args.Count -eq 1)
    {
        $BaseVariableName = $args[0]
    }
elseif ($args.Count -eq 2)
    {
        $BaseVariableName = $args[0]
        $LengthSuffix = $args[1]
        
    }

Function Write-Message(
	[parameter(Mandatory=$true)]
	[ValidateSet("Info", "Warning", "Error", "Verbose")]
	[String] $Severity,
	[parameter(Mandatory=$true)]
	[String] $Message
)
{   
    if((Test-Path -Path  $LogFile))
        {
    	    Add-Content -Path "$($LogFile)" -Value "$(([System.DateTime]::Now).ToString()) $Severity - $Message"
        }
    else
        {
            New-Item -Path $LogFile -ItemType File
        }
    Switch ($Severity)
        {
    	    "Info"		{$FColor="gray"}
    	    "Warning"	{$FColor="yellow"}
    	    "Error"		{$FColor="red"}
    	    "Verbose"	{$FColor="green"}
    	    Default		{$FColor="gray"}
        }
    Write-Output "$(([System.DateTime]::Now).ToString()) $Severity - $Message" -fore $FColor
}

$BaseVariableList = @()
$BaseVariableName = "App"
$LengthSuffix = 2


$objSMSTS = New-Object -ComObject Microsoft.SMS.TSEnvironment

$SMSTSVars = $objSMSTS.GetVariables()

$SMSTSLogPath = $objSMSTS.Value("_SMSTSLogPath")

if (Test-Path $SMSTSLogPath)
    {
        $LogFile = $(Join-Path $SMSTSLogPath Apps_variables.log)
    }

#Writing the Variables to Logfile
Write-Message -Severity Info -Message "This is the Dynamic Variable List BEFORE rebuilding it."

foreach ($Var in $objSMSTS.GetVariables())
    {
        if ( $Var.ToUpper().Substring(0,$var.Length-$LengthSuffix) -eq $BaseVariableName)
            {
                Write-Message -Severity Info -Message "$($Var) = $($objSMSTS.Value($Var))"
                $BaseVariableList += @{$Var=$objSMSTS.Value($Var)}
            }
    }

$objects = @()   
$fixed = @()
$objects = $BaseVariableList

[int]$x = 1
# Writing the variables to Logfile after being reordered
Write-Message -Severity Info -Message "------------------------------------------------------"
Write-Message -Severity Info -Message ""
Write-Message -Severity Info -Message "This is the Dynamic Variable List AFTER rebuilding it."

foreach ($i in $objects) 
{ 
    $Name = "$($BaseVariableName){0:00}" -f $x
    $Value = "$($i.Values)"
    $fixed += @{$Name=$Value}

    Write-Message -Severity Info -Message "$($Name) = $($Value)"

    $x++
    $Name = ""
    $Value = ""
    
}

$BaseVariableListFixed = @()
$BaseVariableListFixed += $fixed



foreach ($BaseVariable in $BaseVariableListFixed)
    {
        
        ""
        $objSMSTS.Value("$($BaseVariable.Keys)") = "$($BaseVariable.Values)"
    }

The idea of the script is still the same. You need to have a prefix on what to search and re-write the numbers as shown in the picture.

This also can be done to computers already installed. Meaning that you can run task sequence over and over again but hide progress bar for it. This means you can have your AD groups that guide your application installation. Running all AD groups against their variables will automatically detect correctly installed apps and re-apply missing ones or add the new ones. Please do not use this. This is not really clever way to use this. Its just an example.

I am quite sure there are ton of ways I have missed the “how you might use these”. But the idea of how and why you might want to add these to your repertoire could be in those example scenarios. Or better yet have your own idea what suits you and your own environment.

If variable app name does not exists it does make an error in smsts.log:

Application policy for ‘WrongAppNameHere‘ not received. Make sure the application is marked for dynamic app install. Policy download failed, hr=0x80004005.

So its not really unknown app. Variable is clearly written in smsts.log. And smsts.log will be your friend on debugging problems.

If I’d do my this on my own environment I’d probably would go for premade computer accounts with AD group based install. This can also be made so you copy the ad groups from an example computer. You could do this by running query against the old computer and create the computer account with the same ad groups. It would be quite an easy function to build and should be easily maintained.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *