top of page

Scripted Import and Deployment of MSI

​

The following script provides a fully automated import of an MSI into ConfigMgr with the following actions:

  • Imports MSI and creates an application, with the option to type in a custom unattended command

  • Creates a AD Group for the clients to be added to.

  • Create a Collection for Installation with a AD Group query

  • Create a Collection for software removal based on Compliance, queries for the software and removes application when the installation is no longer being applied.

  • Distributes the application to the a DP Group

  • Creates Install and Uninstall deployments and assigns to the corresponding Collection.

​

There are 2 remaining tasks, add the clients to the AD Group for software deployment and update the application with OS requirements. 

​

<#
.Synopsis

Scripted Import and Deployment of MSI's

​

.Description

​

.Version

#>

#Set Varibles for Group name and Collection
#$APP is the name of the Application to be used for Collection and Application Creation


param (

#Name of Application eg Office 2019
[string]$App = (read-host "Enter the name of the App"), 

​

#Description of Application                                 
[string]$comment = (read-host "Descriptive Information"), 

​

#Version of App designated with V at the beginning                                  
[string]$AppVer = (read-host "Application Version beginning with a V"),  

​

#Who manufactured the product                 
[string]$AppMan = (read-host "Application Manufacturer"),

​

#UNC Server and Share are set as a variable, path to msi is only required application\microsoft\scom\scomagent.msi                               
[string]$AppPathFolder = (read-host "Enter the path to the MSI from sub-folder under SMSSource application\microsoft\scom\scomagent.msi"), 

​

#Override the default msi installation string               
[string]$installCMD = (read-host "Enter Install command and parameters, if it differs from default. Enter 'N' or leave null to ignore"), 

​

# Type R or A for available or required                      
[string]$AvailReq = (read-host "Enter the Deployment type of 'R' Required or 'A' Available")

)

 

#Takes A or R and makes then the correct input for deployment
if ($AvailReq -eq "R"){$AvailReq = "Required"}
if ($AvailReq -eq "A"){$AvailReq = "Available"}

​

#Variables to create the AD Groups and Collections
#P is for Physical, V is virtual and U for users

$Type = "P"

​

#Set Variable for Group, Collection creation
$ADGroupName = "SW_" + $Type + "_" + $App + "_Install"


#Installation Collection and Application Names
$CollAppName = $App + " Install"

​

#Uninstall Collection and Application Names
$CollAppNameUn = $App + " UnInstall"


##########################################################################
#############  DECLARE VARIABLES FOR CONFIGMGR AND AD  ##########################
##########################################################################
#Site server and site variables

Import-Module $env:SMS_ADMIN_UI_PATH.Replace("\bin\i386", "\bin\configurationmanager.psd1")
Import-Module ActiveDirectory

​

$GetSite = Get-CMSite
$SiteServer = $getSite.ServerName
$Site = $getSite.SiteCode

​

$DP = Get-CMDistributionPoint | Select-Object NetworkOSPath
$DPName = $dp.NetworkOSPath.Replace("\\","")


$DPGroup = Get-WmiObject -Namespace “Root\SMS\Site_$($Site)” -Class SMS_DistributionPointGroup -ComputerName $SiteServer | Select-Object name


#Update this to UNC of the SMS Source path
#########  UPDATE ME  ###########

$SMSSource = "\\ConfigMgr01\SMSSource\"


#Full unc path to the msi
$AppPath = $SMSSource + $AppPathFolder

​

#AD OU Path for Group creation
New-ADGroup -Name "$ADGroupName" -SamAccountName $ADGroupName -GroupCategory Security -GroupScope Global -DisplayName "$ADGroupName" -Path "ou=SoftwareGroups,dc=tenaka,dc=loc" -Description "$comment"


#Connects to the the Site Server 
$SiteSrv = $Site + ':'
CD $SiteSrv

​

# Sets Collection Schedules 
$schedule = New-CMSchedule –RecurInterval Days –RecurCount 7
$scheduleUn = New-CMSchedule –RecurInterval Days –RecurCount 1

​

#Creates the Install Collection and Query
New-CMDeviceCollection -RefreshSchedule $schedule  -comment $comment -name $CollAppName -LimitingCollectionName "All Workstations" -RefreshType Both
Add-CMDeviceCollectionQueryMembershipRule -RuleName $CollAppName -Collectionname $CollAppName -QueryExpression "select *  from  SMS_R_System where SMS_R_System.SecurityGroupName = 'TENAKA\\$ADGroupName'"

​

#Creates the Uninstall Collection and Query
New-CMDeviceCollection -RefreshSchedule $scheduleUn  -comment $comment -name $CollAppNameUn -LimitingCollectionName "All Workstations" 
Add-CMDeviceCollectionQueryMembershipRule -RuleName $CollAppNameUn -Collectionname $CollAppNameUn -QueryExpression "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_AppClientState ON SMS_G_System_AppClientState.MachineName = SMS_R_System.Name WHERE SMS_G_System_AppClientState.ComplianceState = '1' AND SMS_G_System_AppClientState.AppName = `'$App'"


#Creates and imports Applications
#Creates application with a custom installation string

function MSICMD
{

New-CMApplication -Name $CollAppName -AutoInstall $True -Description $comment -SoftwareVersion $AppVer -Manufacturer $AppMan 
Add-CMMSiDeploymentType -ApplicationName $CollAppName -DeploymentTypeName $CollAppName -ContentLocation $AppPath -AddLanguage "en-GB" -Comment $comment -InstallationBehaviorType InstallForSystem -InstallCommand $installCMD -RebootBehavior NoAction

}

​

#Creates application with default installation string 
function MSINoCMD
{

New-CMApplication -Name $CollAppName -AutoInstall $True -Description $comment -SoftwareVersion $AppVer -Manufacturer $AppMan 
Add-CMMSiDeploymentType -ApplicationName $CollAppName -DeploymentTypeName $CollAppName -ContentLocation $AppPath -AddLanguage "en-GB" -Comment $comment -InstallationBehaviorType InstallForSystem -RebootBehavior NoAction

}

​

​

#check is there is a valid custom and valid installation string
if ($installCMD -eq "N" -or $installCMD -eq ""){MSINoCMD}
else {MSICMD}

​

#Push Content to DP's

Start-CMContentDistribution -ApplicationName $CollAppName -DistributionPointGroupName $DPGroup.name

​

#When Available is selected a warning is generated if the command contains -DeadlineDateTime

if ($AvailReq -eq "Avaialble")
{

#Installation Deployment 
#Available from 1 hour and deployed in 7 days

$DeadlineDateTime = (Get-date).AddDays(7)
$AvailableDateTime = (Get-date).AddHours(1)
New-CMApplicationDeployment -Name $CollAppName -CollectionName $CollAppName -DeployAction Install -DeployPurpose $AvailReq -AvailableDateTime $AvailableDateTime -UserNotification DisplaySoftwareCenterOnly


#Uninstall Deployment 
#Install overrides uninstall, once the client is removed from the collection the uninstall will 

$DeadlineDateTimeRem = (Get-date)
$AvailableDateTimeRem = (Get-date)
New-CMApplicationDeployment  -Name $CollAppName -CollectionName $CollAppNameun -DeployAction Uninstall -DeployPurpose $AvailReq -AvailableDateTime $AvailableDateTime -UserNotification DisplaySoftwareCenterOnly

}

 

if ($AvailReq -eq "Required")
{

#Installation Deployment 
#Available from 1 hour and deployed in 7 days

$DeadlineDateTime = (Get-date).AddDays(7)
$AvailableDateTime = (Get-date).AddHours(1)
New-CMApplicationDeployment -Name $CollAppName -CollectionName $CollAppName -DeployAction Install -DeployPurpose $AvailReq -AvailableDateTime $AvailableDateTime -DeadlineDateTime $DeadlineDateTime -UserNotification DisplaySoftwareCenterOnly


#Uninstall Deployment 
#Install overrides uninstall, once the client is removed from the collection the uninstall will 

$DeadlineDateTimeRem = (Get-date)
$AvailableDateTimeRem = (Get-date)
New-CMApplicationDeployment  -Name $CollAppName -CollectionName $CollAppNameun -DeployAction Uninstall -DeployPurpose $AvailReq -AvailableDateTime $AvailableDateTime -DeadlineDateTime $DeadlineDateTime -UserNotification DisplaySoftwareCenterOnly

}

​

​

​

​

​

​

​

bottom of page