Why read this post?
We have recently added 4 new Component Monitors into the Centrastage ComStore:
These monitors utilise PowerShell scripts that call cmdlets within Exchange. As Exchange 2007 and 2010 will only run on 64-bit Server Operating Systems, these cmdlets are only available to the PowerShell scripts if the CentraStage Agent is running as a 64-bit service. The Platform update on Monday 19th March 2012 included the CentraStage Agent version 4.4.1506.1506 which will run as a native 64-bit service on 64-bit Windows Operating Systems. And therefore, these Component Monitors are now available for Exchange administrators to use in CentraStage.
Why read this post?
The files mentioned in this post are available to download from here
Limited user permissions can be a pain when you want to run a job in the logged on user session but require Admin rights in order for it to work correctly. The default behaviour for CentraStage is to run all jobs in the Local System account which has full rights and permissions across all areas of the operating system. This is great and works for almost all of the things that you are likely to want to do with CentraStage. There are some notable exceptions however:
In the case of the uVNC Mirror Drivers this can be a major headache. The uVNC Mirror Drivers are important to get the best performance out of the CentraStage shared screen session functionality. More on this soon…
CentraStage allows you to specify to run the job in the user session (Advanced Options – Execution) in the scheduler. Here’s a screenshot to jog your memory:

With the options set as in the above screenshot, the job will wait indefinitely until a user with Admin rights logs on to the device and then execute the job in the user session. If your end users never log on with Admin credentials then your jobs will never be able to run.
The problem we have however is that you may have whole businesses over multiple sites and on separate domains that have all of their users logging in with limited user rights. Pretty sensible from an IT Management point of view but wreaks havoc with our plans of administering from a central location with CentraStage.
What we really want is to be able to use the following settings which will execute at any user login but have the elevated rights of an Admin:

There is a way to do this and it is up to you whether you see this as a good fit for your environment. The solution I suggest is to create a consistent Domain Admin user across all of your Domain Controllers that you can subsequently reference in CentraStage scripts. Using the LSRUNAS.exe command line tool will allow you to run commands within the user session but with the elevated rights of the Domain Admin previously created.
We’ll get to how you script this with CentraStage in a minute but first a little more on the strategy itself.
You may consider creating a Domain Admin user across all accounts a security risk but bear with me as I’m pretty sure you will agree that this is a non-issue after you hear what I have to say next.
By storing the Domain Admin username and password in CentraStage as account variables, they can be referenced in any scripts without having to ever store the usernames and passwords in the commands in plain text.
Important!
The Domain Admin username and password will never appear in plain text in any of the scripts that land on the remote device.
Also
All CentraStage traffic is encrypted so there’s no chance of anyone sniffing packets as they are transferred around the network.
The last point to note is that you can make the password as strong as you like as it will only be entered once within the CSM and can be hidden from view. Go ahead and make them as crazily complicated as you want. You can even have a look over at https://www.grc.com/passwords.htm to come up with something that would be virtually impossible to type in even if you tried!
An example of the password that I got when I tried this site using the 63 random printable ASCII characters option was:
>fXDG`Qpf\Rq!DY.]Y”NVTx`n”$”`(cA\^’\[=$UrDCB’Wd(l*0s`rz3E?b)&dJ
Certainly not something that anyone trying to log in with this user would be able to guess that’s for sure! According to http://howsecureismypassword.net/, this particular password would take a desktop PC “About 10 trestrigintillion years” to crack!
So the first step on this journey is to get these variables into the CSM (My Account – Settings – Variables)

These variables will now be available to call in any of your scripts using the following environment variables:
%cs_admin_un%
%cs_admin_pw%
The variables will be available from jobs run across any profile as they have been set up at the account level. This really will be the last time you need to enter or even remember what that password is.
The next step is to run a Component against your desired Domain Controllers to add the Domain Admin user. This is easily accomplished using the DSADD command from the Local System account and doesn’t require you to know any existing passwords or anything else in order to do so.
The format of the command that I’m using is as follows:
DSADD USER “CN=%cs_admin_un%, CN=Users, %domain_info%” -samid %cs_admin_un% -desc “CentraStage DA” -pwd %cs_admin_pw% -disabled no -acctexpires never -pwdneverexpires yes -mustchpwd no -canchpwd no -memberof “CN=Domain Admins, CN=Users, %domain_info%”
That looks like some pretty brutal syntax right there! Breaking a long command line down with each switch per line can help readability in a situation like this:
DSADD USER “CN=%cs_admin_un%, CN=Users, %domain_info%”
-samid %cs_admin_un%
-desc “CentraStage DA”
-pwd %cs_admin_pw%
-disabled no
-acctexpires never
-pwdneverexpires yes
-mustchpwd no
-canchpwd no
-memberof “CN=Domain Admins, CN=Users, %domain_info%”
You should be able to see fairly easily how the command line works once broken down like this. I’ve specifically chosen to set the account to never expire, password to never expire and cannot change password. This is so that people can’t mess up the password settings and you won’t be faced with any on-going maintenance.
You’ll notice in the above command that there is a variable referenced called %domain_info% which we haven’t set anywhere within CentraStage just yet. This is because this piece of information changes with every domain and so I’m going to use a tiny snippet of VBScript in order to get the RootDSE in the Distinguished Name format. If not using variables to populate this information then the first part of the command would look something like this:
DSADD USER “CN=Username, CN=Users, DC=MyDomain, DC=com”
The elements here starting with DC are the bits that change every time so we can’t fix the information into the script or even use CentraStage profile variables very easily without a whole lot of messing about. So the easiest answer is to do this “on the fly” at run time. Check out this snippet of VBScript:
Set objRootDSE = GetObject("LDAP://rootDSE")
strDefaultNamingContext = objRootDSE.Get("defaultNamingContext")
WScript.Echo strDefaultNamingContext
All this does is read the RootDSE of the domain and fire it back out of the StdOut in the Distinguished Name format. Luckily we can use a simple batch command to call this piece of VBScript and read the output directly into a variable for use later on:
FOR /F “usebackq delims=” %%i IN (`CSCRIPT GetDomainDNC.vbs`) DO SET domain_info=%%i
The VBScript snippet is just saved in a file called GetDomainDNC.vbs and attached to the Component.
So enough explanation here’s the completed command in all its glory:
@ECHO OFF :: Force working directory to be current directory PUSHD %~dp0 :: Run GetDomainDNC.vbs and read into %domain_info% variable FOR /F "usebackq delims=" %%i IN (`CSCRIPT GetDomainDNC.vbs`) DO SET domain_info=%%i :: Run DSADD USER command to add Domain Admin User DSADD USER "CN=%cs_admin_un%, CN=Users, %domain_info%" -samid %cs_admin_un% -desc "CentraStage DA" -pwd %cs_admin_pw% -disabled no -acctexpires never -pwdneverexpires yes -mustchpwd no -canchpwd no -memberof "CN=Domain Admins, CN=Users, %domain_info%"
The flip side of this is when you want to remove the user in which case we would use the following very similar command just substituting the DSADD command for the much simpler DSRM command:
@ECHO OFF :: Force working directory to be current directory PUSHD %~dp0 :: Run GetDomainDNC.vbs and read into %domain_info% variable FOR /F "usebackq delims=" %%i IN (`CSCRIPT GetDomainDNC.vbs`) DO SET domain_info=%%i :: Run DSRM command to remove Domain Admin User DSRM "CN=%cs_admin_un%, CN=Users, %domain_info%" –noprompt
So that takes care of adding and removing our CentraStage Domain Admin user so next up is an example of how you can use this in a script via the LSRUNAS.exe mentioned earlier.
According to http://www.moernaut.com/default.aspx?item=lsrunas:
LSrunas can be used to run a command using another user account and passing the password as a parameter. This is a big improvement over the standard runas tool which is not able to accept a password. LSrunas can be used in scripts.
The LSRUNAS.exe command line tool is included in the .ZIP file that accompanies this blog post.
An example of a command that could be used to take advantage of this would be:
@ECHO OFF PUSHD %~dp0 SET command="CCleaner.exe /AUTO" lsrunas /user:%cs_admin_un% /password:%cs_admin_pw% /domain:%cs_domain% /command:%command% /runpath:.
The %cs_admin_un% and %cs_admin_pw% variables are being pulled from the Account variables that were defined earlier. The eagle eyed among you will also see that there is a %cs_domain% variable in there too. This is a hidden CentraStage variable that is passed along with the job from the audit data for the device. This ensures that it will dynamically change the domain based on the device that is being targeted in the script.
Setting the %command% variable within the script allows you to put whatever command (or executable as in the example) you want to execute with the elevated credentials. If you want to execute a whole series of commands with these credentials then I would suggest attaching them contained within a batch file to the component and calling the batch file itself in a command.
Hopefully that’s not too much to digest in one go but it will be important in the next follow up post that will discuss problematic installations when strategizing a uVNC Mirror Driver rollout.
Just download the files from the beginning of the post and follow through one step at a time. I’m sure you’ll be fine!
Until next time…
Why read this post?
The files mentioned in this post are available to download from here
Cleaning up unwanted files is one of the most common things that people want to do to help keep a device running smoothly. We have a few different components in the ComStore which touch on this aspect of maintenance but probably the most famous and complete packages out there for doing this job is CCleaner by Piriform (www.piriform.com).
I have experimented with using CCleaner and CentraStage in the past but I found the customisation options limiting when running on multiple devices with all sorts of different software installed.
I’ll try to explain here why…
It is possible to customise the options within CCleaner by including a file called ccleaner.ini in the same directory as the main executables (CCleaner.exe and CCleaner64.exe). An example of the contents of a simple .ini file is shown below:
[Options]
WINDOW_MAX=1
WINDOW_LEFT=274
WINDOW_TOP=123
WINDOW_WIDTH=733
WINDOW_HEIGHT=524
UpdateKey=02/09/2012 09:15:56 PM
(App)Autocomplete Form History=True
(App)Saved Passwords=True
Apart from some Window positioning and update information at the top, the only thing this .ini file would do is turn on cleaning of “Autocomplete Form History” and “Saved Passwords”.
The portable version of CCleaner will always generate this .ini file after the first run but (I think) by default the installed versions of CCleaner do not. You can however enable this from within the main program checking the box under “Options – Advanced – Save all settings to INI file”.

Great, job done! Not quite…
The ccleaner.ini file will record the clean settings if modified from the defaults for the software detected on the machine that it is being run on. For example if I only have Internet Explorer and Firefox on the device that I’m generating the .ini file from then these will be the only things that I have the options to configure.
What happens if I run it on another device that has Chrome, Safari or Opera?
Well as CCleaner doesn’t see anything about these programs in the .ini file it will just use the defaults and go ahead and clean them anyway. This is true of EVERY program that CCleaner supports. This list of programs is extensive. Apart from the “big five” browsers there are another 248 apps that CCleaner will clean unless you tell it not to in the .ini file. Herein lays the problem. Unless you happen to have every version of Adobe Reader from version 5 to version 10 on the device that you are setting up your master .ini file on, then you haven’t got much of a hope of setting up an appropriate .ini file to configure CCleaner for this app.
Just because I don’t have Adobe Photoshop CS5 (supported app) on my device, doesn’t mean that one of my customers won’t. I’m not entirely sure that they’d appreciate having all of their “VisitedDirs” and “FileList” whipped out from under their nose when all you really wanted to do was clean out their 10GB Windows temporary folder and 20GB of Internet browser caches!
I’m sure we’d all like to avoid telephone conversations such as…
Customer: “All of my bookmarks have disappeared”
Engineer: “Bookmarks?”
Customer: “Yes all of my bookmarks. When I start to type something in the bar at the top of Internet Explorer it shows me my bookmarks”
Engineer: “Ahh, that’s not your bookmarks, it’s your Internet history”
Customer: “Well it’s gone and now I can’t get to any of my websites that I use all of the time”
Anyway, you get the idea!
Well that’s that then, bye bye CCleaner…
Wait! Not quite.
This wouldn’t be much of a post if I just pointed out why CCleaner wasn’t appropriate for use within CentraStage now would it? We try to focus on solutions and not problems around here so my natural curiosity was piqued and I figured “there must be a way round this”. Turns out I found one!
CCleaner uses some embedded .ini files of its own to determine what is shown in the list of options that you have to choose from when CCleaner fires up. These files are:
winapp.ini - Application settings
winreg.ini - Registry settings
winsys.ini - System settings
You can export these files from the main .exe using a pretty well undocumented command line like this for the 32-Bit and 64-Bit version respectively:
CCleaner.exe /EXPORT
CCleaner64.exe /EXPORT
This will dump the embedded .ini files into the same directory as the executables and give you an insight into what’s going on “under the hood” when CCleaner does its cleaning. If you’re going to open these files and have a poke around then I would advise using Notepad++ (available from ComStore) as it makes it much easier to see what is going on with it’s syntax highlighting.
Where this gets really interesting is that if you rename these files to winapp1.ini, winreg1.ini and winsys1.ini and include them in the same directory as the executables when CCleaner runs, it will override the embedded .ini files and use these instead! This gives you complete control over what CCleaner presents as options for cleaning in the main app window (and what is cleaned using the silent switch. More on that later).
Renaming these to winapp2.ini, winreg2.ini and winsys2.ini will allow you optionally add locations to clean as well for custom application. I’m not going to get into adding applications here as this is well documented on the Piriform site (link). What we’re interested in is reducing the cleaning options in order to be less aggressive when running on systems with an unknown configuration.
So if we wanted to take this to the extreme and remove all application support and only clean the Recycle Bin for example we could reduce the files to the following (comments removed from file):
Winapp1.ini
[Global]
Revision=2086
NextIDValue=2286
Winreg1.ini
[Global]
Revision=2013
NextIDValue=3016
Winsys1.ini
[Global]
Revision=2043
NextIDValue=1043
[Empty Recycle Bin]
ID=1012
LangSecRef=3003
LangRef=3141
Default=True
SpecialKey1=N_TEMP_RECYCLEBIN
Running CCleaner now will only show a lonely Recycle Bin option in the main window as shown below.

Now using CCleaner to only empty the Recycle Bin is maybe a little overkill but I’m just trying to illustrate a point and I’m sure you can find a happy medium somewhere in there. I would however strongly consider removing anything related to cookies and browser history as people really don’t like losing their passwords to websites if they are stored in the browser. But it’s up to you whether you would consider this a security risk. More on cookies in a sec…
The advantage here is that all other programs that may be installed on your clients systems are safe from unwanted attention from CCleaner when running in silent mode and it also makes it a lot safer to install and have them run it themselves if necessary without fear that they are going to screw things up by running the Registry Clean for example. The options to do any damage simply aren’t there!
If you are feeling brave and want to delve into the murky world of browser cookies then there is a use for the much berated ccleaner.ini that I was talking about at the beginning of the post (come back, all is forgiven!)
Under “Options – Cookies” in the main UI you will see a couple of windows, one being “Cookies to keep”. This will stop the cleaning of any cookies containing the text in that window. CCleaner has some kind of Smart Scanner thing that runs when you first fire it up on a machine which is where it decided that the cookies that you see in the image below were safe to keep. I’m sure that there are others but I’d imagine the definition of what is safe is fairly broad.

This list of “Cookies to keep” is mirrored in the ccleaner.ini file too. Here’s an example of mine here:
CookiesToSave=google.com|mail.google.com|yahoo.com
You can add this line into the ccleaner.ini file to prevent cleaning cookies of known safe sites. Just make sure that this file is in the same directory as the main CCleaner executables.
If I’m honest, this last step could be more trouble than it’s worth unless you have psychic abilities and know what cookies all of your customers may consider valuable. Maybe follow my earlier advice and steep clear of cookies altogether as they aren’t exactly a massive disk space hog.
So let’s look at how this can be run using CentraStage to proactively keep your users devices in check.
CCleaner portable is our friend here and can be downloaded from the Piriform CCleaner “builds” page (http://www.piriform.com/ccleaner/builds). In order to get this to run you only need the following files which can be uploaded to a Component:
CCleaner.exe
CClenaer64.exe
portable.dat
There are some other files and folders in there such as the Lang folder (additional languages) and the License.txt (make sure you read it first!) which you can ditch for the purposes of making your Component. Also if you’re going to use the custom .ini files then pop them in there too. You can simply use the /AUTO command line switch to get CCleaner running silently.
Luckily for us the .ini files are the same for both 32-Bit and 64-Bit versions so no doubling up on the work for us here. You can use the following Batch command:
@ECHO OFF PUSHD %~dp0 IF EXIST "%programfiles(x86)%" (GOTO 64-Bit) ELSE (GOTO 32-Bit) :32-Bit ECHO 32-Bit O/S detected, running CCleaner.exe... CCleaner.exe /AUTO GOTO end :64-Bit ECHO 64-Bit O/S detected, running CCleaner64.exe... CCleaner64.exe /AUTO GOTO end :end ECHO Done!
PLEASE PAY ATTENTION TO THE NEXT SECTION AS IT IS VERY IMPORTANT

Targeting a weekly job schedule against a filter is a good idea as it keeps your managed devices under control without you having to micro-manage them when they get a bit full up.
So that’s about it. I don’t think I’ve missed anything so thanks for sticking with me all this way (if anyone is still here…) and we’ll see you next time.
Take care