PDQ.com mobilePDQ.com desktop
Support

Automating Software Installs for Imaged Computers

Stephen Valdinger
·

Today we’ll look at automating software installs for imaged computers, all while saving yourself some storage space and more importantly…time.

Before you get started here, you’ll want to have an Active Directory security group and OU for imaged machines set.

Automating Software Installs for Images Computers PowerShell code

The PowerShell code is really pretty straightforward. It looks to the OU you created where machines will be dropped after they are added to Active Directory by the imaging process. You can set the frequency to whatever fits best with your environment.

New additions to this OU will be assigned to the security group you create, and once they are deployed and moved out of the Imaging OU and into the OU where they will serve their life sentence, the script removes them from the security group. This all syncs up with the dynamic collection you will create in PDQ Inventory!

It’s pretty slick in once you have an image created, and machines in the OU, the PowerShell script works with PDQ Deploy and PDQ Inventory to deploy your baseline applications to the machines. The script will also generate email notifications, alerting you to any changes that it has made to the security group.

#######################################################
# END USER DEFINED VARS #
#######################################################
#Array for computers that will be removed
$removed = @()
#Array of hostnames stripped from $search
$sanitized = @()
#Array of hostnames stripped from $members
$memsanitized = @()
#########################################################
# CONTAINERS FOR CHANGED HOSTS #
#########################################################
#table for hosts added to the Baseline group
$addedtable = New-Object System.Data.DataTable "Added Hosts"
$addedcolumn = New-Object System.Data.DataColumn Name, ([string])
$addedtable.Columns.Add($addedcolumn)
#table for hosts removed from the baseline group
$removedtable = New-Object System.Data.DataTable "Removed Hosts"
$removedcolumn = New-Object System.Data.DataColumn Name, ([string])
$removedtable.Columns.Add($removedcolumn)
####################################
# ADD TO GROUP #
####################################
Foreach ($s in $search){
$sanitized += $s.SamAccountName
}
#If exists in group, skip, else add.
Foreach ($san in $sanitized){
If (Get-ADGroupMember "TUSC Baseline" | Where { $_.SamAccountName -eq $san}){
Out-Null
}
Else {
Add-ADPrincipalGroupMembership -Identity $san -MemberOf "$securitygroup"
#actually add data to added table.
$addedrow = $addedtable.NewRow()
$addedrow.Name = $san
$addedtable.Rows.Add($addedrow)

}
}
########################################
# REMOVE FROM GROUP #
########################################
#Trim group members down to a new array of just hostnames
Foreach ($mem in $members){
$memsanitized += $mem.SamAccountName
}

#Do some logic that compares the array and dumps differences to a new array. This array will contain members that need the group stripped away.
Foreach ($ms in $memsanitized){
If ($sanitized -contains $ms){
Out-Null

}
Else {
$removed += $ms
}
}
#If there is actually something in the $removed array, take action and removed that machine from the group.
If ($removed -ge 1) {
Foreach ($rem in $removed){
Remove-ADPrincipalGroupMembership -Identity $rem -MemberOf "$securitygroup" -Confirm:$False
#add data to removed table
$removedrow = $removedtable.NewRow()
$removedrow.Name = $rem
$removedtable.Rows.Add($removedrow)
}
}
#Counts on the datatables to determine if email will be sent.
$acount = $addedtable.Rows.Count
$rcount = $removedtable.Rows.Count
If ($acount -and $rcount -eq 0) {
Out-Null
}
Else {
###########################################################
# CONVERSION TO HTML TABLE FOR EMAIL #
###########################################################
#This builds the table for machines added to TUSC Baseline
$ahtml = "<br><table><tr><td>Hostnames Added to TUSC Baseline</td></tr><br>"
foreach ($arow in $addedtable.Rows){
$ahtml += "<tr><td>" + $arow.Name + "</td></tr>"
}
$ahtml += "</table> <br>"
#This builds the table for machines removed from TUSC Baseline
$rhtml = "<br><table><tr><td>Hostnames Removed from TUSC Baseline</td></tr><br><br>"
foreach($rrow in $removedtable.Rows) {
$rhtml += "<tr><td>" + $rrow.Name + "</td></tr>"
}
$rhtml += "</table>"
########################################################
# SEND EMAIL REPORT #
########################################################
#Send the message
#Send-MailMessage -SmtpServer $smtpserver -From $from -to $to -Subject $subject -Body $body -BodyAsHtml
}
$addedtable.Dispose()
$removedtable.Dispose()
Exit

Run this script as a scheduled task. You will want to create the task to run as an account that has been delegated access to manage group memberships in Active Directory. I recommend setting up the scheduled task as a Service Account that has been delegated access to change group memberships in Active Directory.

Also, the Start A Program line you will want to use for the executable is the path for Powershell (Typically C:\windows\WindowsPowershell\v1.0\powershell.exe) and in the Arguments field use:

-noprofile

Don't miss the next post!

Using PowerShell to Install Printers

When installing printers, we will need to do the four things; Add Driver to the Store, Install the Driver, Create Printer Port, and Install the Printer