PowerShell scripting template for SCCM packages

This article provides a PowerShell scripting template for SCCM and MDT packages. This template can also be used for stand-alone installations (without using SCCM or MDT)!

An SCCM package is basically a container with source files. I recommend using a wrapper (a script) to execute the installation files and for any configuration you may need. And that is exactly what the PowerShell template below offers!
Even better, the template in this article uses my PowerShell Function Library, which effectively turns it into a complete deployment framework.

Change Log
23.05.2017: updated and renamed functions.
05.06.2018: major overhaul of this article and single functions have been replaced by the Dennis Span PowerShell Function Library.
29.12.2019: solved an issue whereby the scripting template in an MDT task sequence does not work properly. I had to change the scope of the variables LogDir and LogFile in the scripting template. The scope for both of these variables is now set to global. If you are not familiar with the concept of scopes please see the Microsoft article About Scopes.

Scripting Template

The scripting template below is an example that you can use for your installations and configurations. The functions in the template are imported from a PowerShell module for the Dennis Span PowerShell Function Library. The library offers more functions than included in the template (the template is only an example).

Please see the article PowerShell Function Library for detailed information how to install and use the library.

For a complete overview of all PowerShell functions included in the library, see the following articles on this website:

How to use this template

First, copy the above code in your preferred editor (e.g. notepad) and save the file as a PowerShell script (*.PS1), for example MyAppInstaller.ps1. You can choose any file name you want of course.

You have to modify a couple of lines in the script to match your specific requirements. Enter your preferred log directory and package name in lines 44 and 45, for example:

  • $BaseLogDir = "C:\Logs"
  • $PackageName = "Adobe Acrobat Reader"


  • $BaseLogDir = "C:\Script\Logs"
  • $PackageName = "Environment_Config"

When the log directory is created, spaces are automatically replaced with an underscore ("_"), for example: C:\Logs\Adobe_Acrobat_Reader.


Changing the main log directory (e.g. C:\Logs) at a later time means that you have to change each script that contains the hard-coded path. There is another, more flexible way:

  • Create an environment variable using a Group Policy Preference called GlobalLogPath (or use a different name). As a value enter your preferred log path, for example "C:\Logs".
  • In the script, add $env:GlobalLogPath as a value to the PowerShell variable $BaseLogDir: $BaseLogDir = $env:GlobalLogPath

The PowerShell script now reads the log path from the environment variable GlobalLogPath. In case you ever want to change the log directory you simply change the path in the Group Policy Preference environment variable without having to change any of your scripts.

The section How to use the library in a PowerShell script in the article PowerShell Function Library describes how to use the library in a PowerShell script. In line 61, make sure to enter the correct path to the library.

In the script sections "Pre-launch commands", "Installation" and "Post-launch commands" make sure to enter the functions you require.

Optional: software (un)installation

In case you are installing or uninstalling software, add your source file(s) to a subfolder relative to the root folder (e.g. Files). The subfolder is the relative path to your package source directory. For example, if this is your package source folder:

\\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01

Than the subfolder for your installation source files is:

  • \\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\Files
    \\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\MSI
  • \\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\SETUP

In the PowerShell script, enter the name of your installation file, arguments and sub folder (again, relative to the root folder).

For example:

  • Line 84: $FileName = "AcrobatReader.msi"
  • Line 86/88: $Arguments =
    • "Transforms=""AcrobatReader.mst"" LANG_LIST=""en_US,de_DE"""
    • "/silent /uninstall"
    • "/QN" (for setup.exe files only)
  • Line 90: $FileSubFolder = "Files"

In the previous example, the folder Files is used for the variable $FileSubFolder, This is the default value, but you can use any folder name you want (e.g. "MSI", or "SETUP"). Just make sure that the folder exists relative to the root of the path.

Please note that for MSI packages the following parameters are added by default:

  • For uninstallations: "/x ""$File"" /qn /norestart /l*v ""$LogFileAPP"""
  • For installations: "/i ""$File"" /qn /norestart /l*v ""$LogFileAPP"""

When you have prepared your PowerShell file copy it in the root of your package source directory. For example:

\\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\AppInstaller.ps1

The PowerShell script is executed as follows:

  • For installations:
    powershell -file "\\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\AppInstaller.ps1" Install
  • For uninstallations:
    powershell -file "\\FileServer1\PackageSource\Adobe\Acrobat Reader\11.0.18_01\AppInstaller.ps1" Uninstall

Happy scripting!

Share this post:
Dennis Span on EmailDennis Span on LinkedinDennis Span on Twitter
Dennis Span
Dennis Span
Dennis Span works as a Lead Sales Engineer at Citrix in Vienna, Austria. He holds multiple certifications such as CCE-V, CCIA and CCEA. In 2017, Dennis became a Citrix Technology Advocate (CTA). In 2019, he became a Citrix Technology Professional (CTP). Besides his interest in virtualization technologies and blogging, he loves spending time with his family as well as snowboarding, playing basketball and rowing. He is fluent in Dutch, English, German and Slovak and speaks some Spanish.

21 thoughts on “PowerShell scripting template for SCCM packages

    • Hi Phil, for sure it works with MDT as well. I do not add any SCCM specific functions in my PowerShell scripts. My scripts also work without SCCM or MDT. You can simply trigger them manually (e.g. powershell.exe -file %FileName%).

  1. Pingback: Google Chrome on Citrix deep-dive - Dennis Span

  2. Pingback: Scripting the complete list of Citrix components with PowerShell - Dennis Span

  3. Pingback: Printer Drivers Installation and Troubleshooting Guide - Dennis Span

  4. Pingback: Citrix Delivery Controller unattended installation with PowerShell and SCCM - Dennis Span

  5. Pingback: Citrix License Server unattended installation with PowerShell and SCCM - Dennis Span

  6. Pingback: Citrix Provisioning Server unattended installation - Dennis Span

  7. Pingback: Citrix Director unattended installation with PowerShell - Dennis Span

  8. Pingback: Citrix App Layering Agent unattended installation - Dennis Span

  9. Pingback: How to configure and run BIS-F in an SCCM task sequence - Dennis Span

  10. Pingback: Citrix StoreFront unattended installation with PowerShell - Dennis Span

  11. Pingback: Citrix Receiver unattended installation with PowerShell - Dennis Span

  12. Hello Dennis,

    Thanks for your work!
    I have a problem with SCCM, the package return an error 196608.
    It works if i run manually the script.
    Have you any idea for this error?

    • Hi Xavier, thanks!

      I am not sure what that error means exactly, but I suggest to check the following:
      -Test the installation as a system user (example: https://dennisspan.com/scripting-the-complete-list-of-citrix-components-with-powershell/#CFsDep2.sys).
      -Also, the process ‘smsswd.exe’ that executes the package runs as a 32-bit process. Make sure that when testing manually you emulate this behavior. Open a 32-bit command window (C:\Windows\SysWOW64\cmd.exe) and run the installation from there.

      In case you require more help, please send me an e-mail (dennis@dennisspan.com) with more details (e.g. exact command line, package settings, etc.). Perhaps you can even send me a copy of the script so I can test it myself.

  13. Pingback: Encrypting passwords in a PowerShell script - Dennis Span

  14. Pingback: Citrix Application Probe Agent unattended installation - Dennis Span

  15. Hi,
    in case you want to install a msi in the post (or pre) section. How do you implement that?
    In my case the logfile is not fully written (broken actually), SCCM says Installation Failed and Post-msi is not installed.

    THx for your reply

  16. Hi Dennis,
    I found my mistake by running the .ps1 manually in powershell
    PS: A nice feature would be a function that searches for a running process and kills it if specified. E.g. DS_SearchRunningProces -process iexplore.exe -Kill yes/no

    • Hi Lieven,

      I am happy you found the mistake. And your idea for a new function to kill a running process is a good idea. I will implement it in the next release of my Function Library.




Leave a Reply

Your email address will not be published.


This site uses Akismet to reduce spam. Learn how your comment data is processed.