Monday, 31 March 2014

A handy hint for troubleshooting PowerShell Actions in AppSense DesktopNow Environment Manager

Verifying that scripts have run successfully in any software is often tricky. AppSense EM is no different. As it has such a powerful integrated scripting capability, you often find yourself doing lots of things with PowerShell and the like. During your test phase, it is often tricky to identify whether a script has run successfully, and even trickier to find the errors if it doesn't.

Of course, you shouldn't use PowerShell or other Custom Actions if a native Action will suffice. Scripted actions can often cause logon or application delays, particularly if they're complicated. So if it's possible, try and keep the scripted stuff to a minimum. It should only be used where the native Actions can't cut it - I've seen lots of cases where AppSense admins have used scripted rules for no other reason than "because we can", and they're probably making their configurations run slightly less than optimally because of this.

Anyway - the situation I found myself in, which was trying to verify whether a scripted Action had run successfully or not, felt somewhat similar to the good old batch days. I used to use the "pause" command in batch files to allow me to verify whether a script had executed successfully or not during the test phase. For instance, say I was running this batch command

md c:\JRR

(which naturally you all know is creating a folder)

I would insert the pause command afterwards, like so

md c:\JRR

So, if the command ran successfully, I would see this at logon

However, if it didn't, I would see the this...

....which tells me handily that the folder already exists. So, for my test phase, the pause command is invaluable. Obviously when we go to production stage, the pause command is removed, and the batch commands are then invisible to the end user.

In AppSense EM, I am primarily working with PowerShell custom Actions. How can we replicate this functionality within the PowerShell we are using?

Firstly, we will create the PowerShell. It makes sense to replicate the function we were using in the batch command above - creating a folder. Now I know I said that you shouldn't use Custom Actions where native Actions would suffice, and if I wasn't trying to demonstrate something, then yes, you should use Action | File and Folder | Create Folder instead!

The PowerShell we need to put in is

New-Item c:\JRR -itemtype directory

Now, there is one more thing we need to do to allow this to run in full view for the test phase, and this is to turn off the EM option for "prevent this script from running interactively", as below

Now we will need to add in the PowerShell command equivalent to wait for the user to press a key. If you simply wanted a pop-up box like the VB MsgBox function, you can - in fact we've used this in a previous article. However, calling out to another window seems a little clunky, so is there a way it can be done natively in PowerShell?

Yes, you can, by using the code below

Write-Host "Press any key to continue ..."

$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

This actually uses PowerShell’s automatic variable $host (which is actually an instance of the .NET Framework class System.Management.Automation.Host) and the ReadKey method. The ReadKey method enables us to get information about the key that has just been pressed. As we're only interested in the fact that a key has been pressed (and not what it is), two parameters are passed. NoEcho - this prevents any information from appearing on screen when the user presses a key, and IncludeKeyDown - this tells the script to continue as soon as a key has been pressed. If you want the script to wait until the user releases the key, use IncludeKeyUp instead. There is a last parameter you could invoke - AllowCtrlC, which would make the script continue during a Ctrl-C keystroke rather than terminating.

So, now we can save this into our configuration, and let's see what transpires.

If the command completes successfully, we see this

And if it doesn't complete successfully, we see this

And once our testing phase is over, we can reset the "prevent script from running interactively" option and comment out the "Press any key to continue" lines from the Action, and our users will not see any of this appear, successful or not.

One caveat to this. If you're using a version of EM prior to 8 FR 4 SP3, you may see this error when the script executes - you'll have to be quick to spot it though!

There is an AppSense technote explaining this behaviour - (may require login). The solution is to upgrade EM to the latest available version.

Hopefully this little trick may help some of you out there perform your testing in a more hassle-free manner. I've certainly found it valuable for troubleshooting scripted PowerShell Actions - although I have no doubt there are many more ways to skin this particular cat, such as logging to a text file or the console.


  1. Hi James,

    Quick questions, what if I want to troubeshoot a PS script that runs at computer startup ?
    I could, as a test, run the script at user login but I think the problem with the PS script is timing related. Any ideas on how to use this tip in my situation ?


    1. Hi Ralph

      You could try setting the script to run interactively and then seeing if appears on the console session at startup, but I doubt this will work, although it's worth a try.

      Failing that, you will have to log your script somewhere (probably using Out-File or such like) or even try the AppSense debug logging tool. Both should hopefully allow you to see when your script tries to run its commands and why they can't complete.



  2. Hi James,
    What could be wrong here? Wrote a powershell script to add a machine to an AD group and "Computer Startup", Scripts runs successfully on it's own but will not perform same when imported into EM.

    1. Possibly it can't contact a domain controller when the script runs? Are you on EM 8.5 and using the Network Connected trigger, that should ensure connectivity is there.

  3. The script is part of a list of actions on the parent node of a multiplenode policy hence why it's been added at computer startup instead of network available node. I can see script works but just does not add the object into the group at start up. I've added it to network available node just now and restarted with no luck

    1. Interesting. Care to share the script and I can have a go? My email address should be on the About Me tab.