How to deploy a PowerShell script with Workspace ONE

There are two ways to deploy a powershell script with Workspace ONE. One is via an area called “Product Provisioning”. This is very similar to “Packages” in SCCM. The other is with the standard “Apps and Books” section (aka Software Distribution). Each method has its strengths and weaknesses and should be used accordingly.

Method 1 – Product Provisioning


  • Very simple way to deploy a basic script with some files
  • No “detection criteria” to worry about – simply fire it off. It will succeed/fail based on the exit code of the script.
  • Can deploy multiple files without having to zip
  • Works in parallel to Software Distribution
  • I’ve found it to work best for scripts that do configuration during initial enrollment


  • Difficult to do version control
  • To update files already deployed to a device, you have to send a delete command first and then update (hence why this method is best suited for initial enrollment)


  1. First, navigate to Devices –> Staging & Provisioning –> Components –> Files/Actions.
    Then click the “Add Files/Actions” button at the top.
  2. Select “Windows”, then “Windows Desktop”.
  3. Fill out the Name and Description. Verify you have the correct Organization Group (OG) in the “Managed by” field.
    ​In my example, I have a script to disable UAC.
  4. Click the “Files” tab and the top and then “Add Files”.
  5. Browse for your PowerShell script.
  6. Fill out the download path where you want the script to be downloaded to on the client.
  7. Click Save.
  8. Now click on the “Manifest” tab and click “Add Action” to configure the actual command to run the script.
    Complete the following:

    • Action(s) to Perform: Run
    • Execution Context: System
    • Command Line and Arguments to run: Enter full path to Powershell script configured in previous step. No need to add any “powershell -executionbypass” commands in front of the file as the Product Provisioning engine automatically runs in bypass mode.
    • TimeOut: Configure as needed.
  9. Add optional “Uninstall Manifest”
  10. Once you added the necessary files and manifests, click Save.
  11. Now, we need to create a “Product” that will be associated with this Files/Action item.
  12. Go up to “Product List View” and click on “Add Product”.
  13. Select “Windows” and then “Windows Desktop”.
  14. Fill the “General Tab” with the appropriate information. Select or create a smart group in the “Assigned Groups” area.
  15. Click on “Manifest” tab, and then “Add”.
  16. Under “Actions to Perform” select “Install Files / Actions”
  17. Under “Files/Actions” select your previous created item. Mine is called “Disable-UAC”.
  18. You can configure additional download or install conditions in the “Conditions” tab. You can modify the deployment schedule in the “Deployment” tab. And you can also add any dependencies in the “Dependencies” tab. For now, I”m leaving all three of these default.
  19. Once ready, click “Activate” to view final device assignment list. If everything looks good click “Activate” again to send down the script.

Method 2 – Apps & Books (Software Distribution)


  • Gives you full lifecyle control over apps and scripts. You can add new versions, remove old, report on install status etc.
  • Will be published to Workspace ONE catalog if you have vIDM
  • A lot more control over the commands to run and install criteria
  • Can be used to export as PPKG as part of Factory Provisioning


  • Takes a little bit longer to setup as there are more fields required (not too bad once you get used to it)
  • If you have apps set to auto deploy, updating a new version will also automatically deploy to those same smart groups

This method is probably most commonly used in conjuction with doing a software install, but driven by a PowerShell script. However, you can “just” deploy a script with this method, but it is more work as there are more fields you have to configure and fill out. I’ll show you how using the same “Disable-UAC” script used in the first example.

  1. Create a folder with your script and corresponding files in it
  2. The Software Distribution engine (SFD) expects an msi or exe file inside of the zip file we will make later. If you are only deploying a script you will either need to include a small EXE or MSI that won’t be used, or simply create a text file and call it “dummy.exe”. 
  3. Select both of these files, right click then Send To –> Compressed (zipped) Folder. NOTE: Don’t go up a level and do this on the parent folder as it will make an additional and necessary sub-folder inside your zip file.
  4. In the Workspace ONE console, browse to Apps & Books –> Applications –> Native. Then click “Add Application”
  5. Click on the “Upload” button and select your zip file.
  6. Click “Save” to upload.
  7. Select correct Organizational Group and then click “Continue”.
  8. On the “Details” tab, fill out the necessary fields. I generally fill out these ones:
    – Name (update the name)
    – Supported Processor Architecture (64bit)
    – Change log (add info and put my username so other admins know who uploaded)
    – Put in Description detailing what this does
  9. Click on “Files” tab
  10. The App Uninstall Process section toward the bottom must be filled out. If you don’t care or need an uninstall command, simply type in dummy text. Note that if you don’t fill this out, this app (or script) will permanently remain on the device even if un-enrolled or enterprise wiped. You can also upload a custom script that does the uninstall.
  11. Click on “Deployment Options” tab.
  12. The first section called “When to Install” (ask Data Contingencies) sets minimum system requirements in order for this to install. One good example would be for OEM type. You can specify a registry key that corresponds to the correct OEM vendor.
  13. Next, the “How to Install” section is the important bit. Select “Device” context, input the Install command, and say “Yes” for admin privileges. Here is a sample command for each context:
    1. Device
      1. powershell -executionpolicy bypass -file Disable-UAC.ps1
    2. User (added parameters to hide powershell windows that pop up. You may still see a black cmd window as our agent has to call powershell from cmd.)
      1. powershell -executionpolicy bypass -nologo -NoProfile -WindowStyle Hidden -file Disable-UAC.ps1
  14. I also recommend setting the “Install Timeout” to 1-5 min so that if it does fail, it doesn’t take forever to report (default 60 min)
  15. And finally, you must fill out the “When to Install Complete” section by telling the SFD engine how to know when this is finished. Click on “Add”.
  16. You have a number of options:
    1. App Exists/App Does not exist – SFD will do an app GUID lookup from win32_product. Here’s a quick script you can run on the client to get GUIDs
      get-wmiobject Win32_Product | sort name | FormatTable IdentifyingNumber, Name, LocalPackageAutoSize
    2. File Exists/Does not exists – Probably the easiest of the list to configure. I often set this to a log file that gets created when the script runs successfully.
    3. Registry Exists/Does not exists – Look at a registry key to determine success. Make sure you use HKLM instead of the full HKEY_LOCAL_MACHINE.
  17. Once you’ve added your detection criteria, click on “Images” tab to upload a icon (optional). Make sure you upload in the “Icon” section and not “Mobile Images”.
  18. Click “Save & Assign” to deploy.

This Post Has 30 Comments

  1. Bobby Hilvert

    A big fan of the dummy.exe method of deploying Powershell scripts. Have had to use it in the past for making registry changes. I like that it provides more detection methods and reoccuring checkin. Is there a way to hide it from the Workspace ONE user application? For example if I was creating a required application and didn’t need it to clutter the App Catalog.

    1. Brooks Peppin

      This is a common ask and it’s on the roadmap to gain this ability.

  2. Jason H

    Awesome blog. Very handy

  3. Brian

    Thanks Brooks, first time putting a .ps1 as a product. I followed your guide and am very pleased that it worked flawlessly. Thanks!

    1. Brooks Peppin

      Thank you!

  4. fawad

    thanks. it was helpful

  5. sam

    is the folder C:\VMware_IT\Logs\ standard? i’ve never seen it on a client and when sending commands (which were successful) i don’t have this log file?

    1. Brooks Peppin

      Hah no that was just what we used internally in our IT group.

  6. Hen Korman

    is there any chance that you can upload an example script that write a log only if the script runs successfully?
    (for the File Exists/Does not exists)
    Thanks alot

    1. Brooks Peppin

      So for this I would just make an if statement in the detection script. If (test-path [path to whatever]) {out-file c:\temp\success.txt}. Then configure the app to look for that file as detection criteria. Additionally, you can make a “script” detection and then configure it to just output a specific exit code (i.e. exit 0 if successful). Configure the “Success exit code to match”.

  7. Jason Williams

    Brooks, how do I go about figuring out why Files/Actions are not working for me. I’m trying to run a simple bat file. File deploys fine to the directory I choose but the the never executes on the client and I am really not sure why. Path looks correct. No bat file works for me. Thanks!

    1. Brooks Peppin

      The first thing I’d check is to ensure your Action has the full path of the file. So if you put the file as “C:\temp\run.bat” in the “Files” section, the “Action” needs to also be “C:\temp\run.bat”.

  8. Hen Korman

    If I’m using Method 2 – Apps & Books (Software Distribution)
    and the script need to call few other files,
    I’m adding to the zip file all the necessary files, but in the script, how do I know the path to call those files?

    1. Brooks Peppin

      Using software distribution, it will always extract the zip and then use the location as the “working directory”. So if a script is in the root of the zip then you can just call “powershell -executionpolicy bypass -file .\script.ps1”. If you have a subfolder, then just add the relative path like this: .\Folder\script.ps1.

  9. Dmort

    Hello, my powershell script needs to be available via the Intelligent Hub so I am using Method 2. The script installs an app which has a GUI. However, when I deploy the script as an App the GUI never pops up. I can see the app process running in task manager but nothing ever opens. I’ve tried everything I can find to get the GUI to show but nothing has worked. Have you ran into this issue at all and found a solution?

    1. Brooks Peppin

      You’ll want to ensure that the “Install Context” is set to “User” and “Admin Privilages” is set to “Yes”. This will allow the GUI to show to the end user. You can also check out my PSADT blog for some additional reference.

      1. Shishir

        Hello, We need to install an application to non admin user and the application has GUI. Is it possible to get GUI with Install Context set to “Device” ?

        1. Brooks Peppin

          Set the install context to “User” and “Admin privelages” to Yes. This will show a UI and still install properly on a non-admin user. Device context installs as “SYSTEM” and it does not have a UI.

  10. PerPilot

    Hi, I have made a ps script that seems to download and run as it should. But I don’t know the file location where it has been installed. Can you advise how to set the installation path?

    1. Brooks Peppin

      What method are you using?

      1. PerPilot

        Hi again, I’m using method 2, apps and books. I have deployed 2 separate scripts this way, the first one changes the password of the local windows administrator and stores it in Azure AD. The second script is supposed to register a monthly task of running the first script.
        So I am actually wondering about 2 things.
        1. The path of the first script ( so I can register the job in task scheduler).
        2. Is there a way to set up dependancy so that I am sure the first script has been installed before running the second?
        Thanks for your help!

        1. Brooks Peppin

          If I were you I’d probably use sensors instead of Apps and books. You could put both of those things together in one sensor and configure it to run as as schedule. Careful though if you have credentials stored in the script as neither sensors or apps and books keep the data encrypted. Sensors are more secure as the call goes directly to the hub and the script isn’t stored anywhere on the client. You can also deploy an “encoded” PS script via a profile

          1. PerPilot

            Thanks for the tip! I will investigate.

  11. Andrew Montague

    I’m getting a lot of issue with this. The error most often appears to be “Final Detection Failed “. In this case it is a simple script that copies a file from the network to a local folder on the W10 machine (a .JAR and .Dll file). The final detection criteria is set to check these files are there but I don’t know if it’s trying to detect the files before they’ve copied or what else might be happening.

    I sure hope Freestyle Orchestrator solves some of the Windows 10 app deployment issues because right now this is a major headache for Workspace ONE.

    1. Brooks Peppin

      Hey Andrew – What does the log say in the registry for that app? HKLM\SOFTWARE\AirWatchMDM\AppDeploymentAgent\S-1-5-18\{guid}\LastDeploymentLog. Open up that key and paste into notepad. Does that give you any more clues? If you want to post or email me the app configuration I can see if anything jumps out.

  12. Charlie

    Brooks, I am using the apps and books method and have the install command exactly matching yours
    “powershell -executionpolicy bypass -file install.ps1”

    The script removes a printer, creates a temp folder and copies an exe to the temp folder to be run by the “start-process” command.

    My script works perfectly locally, but does not run when using apps and books in WS1. The temp folder does not get created, thus causing me to think that the script is not running at all.

    Can you provide any thoughts or troubleshooting steps?

    1. Brooks Peppin

      Hey Charlie. First thing I would check is how are you zipping it? A common issue is that sometimes people zip the folder which then creates a subfolder underneath but they don’t update the install path accordingly. You can check out this page as well for how to look at the logs to see what the error is: The cheat sheet is also here:

  13. Jolle

    This works great, thanks a lot!
    Is it possible to somehow log information from the script that i run (with method 1 or method2) on the client and have that logged information send back into WS1 UEM Console for reviewing? I don’t have WS1 Intelligence (so cant use sensors). Thanks for any tips Brooks!

    1. Brooks Peppin

      Thanks! Unfortunately no, scripts won’t be able to return back log information to the console yet. There is a new native “Scripts” feature coming soon that works with the broader Freestyle feature. This is tech preview for now and will go GA later this year. It probably wont have full logging like what you are looking for but it will log back the success/fail and you won’t have to package it as an App.

Leave a Reply