Client Profile Updating Utility (CPUU) Wrapper (aka EMWProf)

The Client Profile Updating Utility (CPUU) is one of the reasons to purchase Quest Migration Manager for Exchange (QMM/EX).  This utility will update the Outlook profile for migrated users and it will look and act just like the old profile did – all the views, settings and so on.  The downside?  You have to write a wrapper to use it effectively and a good example is not included in the product documentation.  As a result, if you don’t know already the in’s and out’s of writing a good wrapper, you may end up with a poorly performing CPUU.  In this post I will provide some guidance and examples code on writing a good wrapper.

Update 12/9/2013:  Added description in text at end of post to walk through what the cmd file does.
 

There are a few simple rules when running CPUU.

  1. It runs best if it is run locally and  not from a share.
  2. It runs slow if you write the output log to a share (e.g. write the log locally).
  3. If possible, set it to run using the user credentials.  Though running with admin creds may provide some flexibility, it also creates another way that a single service account could create problems (locked out, hacking, and so on).
  4. Go ahead and leave verbose logging on – it isn’t that much text and if you do have a problem with it running you will want the extra detail.

So, with no further ado, here is an example CPUU Wrapper that I routine customize for my customers.

CPUU_Update.CMD

@echo off
REM Set this to the central location where you want to house your log files.
set EMWPROFLOGSSERVER=ServerName
set command_line=
set emwp_ver=
setlocal
REM If running with cached creds assign a value to logonserver.
IF "%LOGONSERVER%" EQU "" set LOGONSERVER=\\DomainController
REM Verify local xml option is in place.  If not, call the script to set it.
IF NOT EXIST %TEMP%\CPUU\autodiscover.xml CALL %LOGONSERVER%\CPUU\SetPreferLocal.CMD
REM *** Check for files locally, if not, copy then locally ***
REM If you need to deply a new version, udate version number.  If you need to update a file, just increase the .A to .B and so on.
set emwp_ver=CPUU-5.4.0.537.A.DAT
IF NOT EXIST %TEMP%\CPUU GOTO CopyFiles
IF NOT EXIST %TEMP%\CPUU\ClientProfileUpdatingUtility.exe GOTO CopyFiles
IF NOT EXIST %TEMP%\CPUU\CPUU.ini GOTO CopyFiles
IF NOT EXIST %TEMP%\CPUU\DlgHookHandler.dll GOTO CopyFiles
IF EXIST %TEMP%\CPUU\%emwp_ver% GOTO RunEmwProf
:CopyFiles
mkdir %TEMP%\CPUU
copy %LOGONSERVER%\Netlogon\CPUU\ClientProfileUpdatingUtility.exe %temp%\cpuu /y
copy %LOGONSERVER%\Netlogon\CPUU\ClientProfileUpdatingUtility_x64.exe %temp%\cpuu /y
copy %LOGONSERVER%\Netlogon\CPUU\CPUU.ini %temp%\cpuu /y
copy %LOGONSERVER%\Netlogon\CPUU\DlgHookHandler.dll %temp%\cpuu /y
REM Update the version file
date /t > %TEMP%\CPUU\%emwp_ver%
time /t >> %TEMP%\CPUU\%emwp_ver%
GOTO RunEmwProf
:RunEmwProf
@set command_line= -Log "%TEMP%\CPUU\CPUU_%username%_%computername%_#h_#d_#t.log" -LogExtended
@if %PROCESSOR_ARCHITECTURE% == x86 (
@set Outlook_arch=x86
) else (
@set Outlook_arch=x86
@for /f "tokens=3" %%i in ('reg query HKLM\Software\Microsoft\Office\14.0\Outlook /v Bitness 2^>nul') do @set Outlook_arch=%%i
@for /f "tokens=3" %%i in ('reg query HKLM\Software\Microsoft\Office\15.0\Outlook /v Bitness 2^>nul') do @set Outlook_arch=%%i
)
@if  %Outlook_arch% == x64 (
@set run_cmd=%temp%\cpuu\ClientProfileUpdatingUtility_x64.exe %command_line%
) else (
@set run_cmd=%temp%\cpuu\ClientProfileUpdatingUtility.exe %command_line%
)
echo %run_cmd%
REM - This executes the command:
%run_cmd%
set EMWP_ReturnCode=%ERRORLEVEL%
 
echo EMWProfReturnCode is %EMWP_ReturnCode% > %TEMP%\CPUU\LOG_CPUU_%username%_%computername%_returncode.log
:CheckEnableAutoDiscover
Echo EMWProf return code is %EMWP_ReturnCode%
REM Get the file...
set fileName=.
set bestNow=.
set bestThen=.
for /f %%a in ('dir /b %TEMP%\CPUU\CPUU_*.csv') DO set fileName=%%a
if %fileName% EQU . GOTO :EndResultCode
REM Parse the file...
for /f "delims= tokens=1-3" %%a in (%fileName%) DO (
    if %%b EQU 2 set bestNow=%%b
    if %%b EQU 10 set bestNow=%%b
    if %%c EQU 2 set bestThen=%%c
    if %%c EQU 10 set bestThen=%%c
)
Echo Best Now %bestNow%
Echo Best Then %bestThen%
:EndResultCode
if %bestNow% EQU 2 GOTO ChangeAutoDiscover
if %bestNow% EQU 10 GOTO ChangeAutoDiscover
if %bestThen% EQU 2 GOTO ChangeAutoDiscover
if %bestThen% EQU 10 GOTO ChangeAutoDiscover
REM ELSE...
GOTO END
REM  Change the Autodiscover XML file to use the target (since we had a successful switch).
:ChangeAutoDiscover
copy %temp%\cpuu\target.xml %temp%\cpuu\autodiscover.xml /y
GOTO END
:END
REM Move the log files to the central server
move /y %temp%\cpuu\CPUU_*.log \\%EMWPROFLOGSSERVER%\emwproflogs$
move /y %temp%\cpuu\LOG_*.log \\%EMWPROFLOGSSERVER%\emwproflogs$
move /y %temp%\cpuu\*.csv \\%EMWPROFLOGSSERVER%\emwproflogs$
Echo Done!
@endlocal

As you can see it is a fairly long script, but it does get the job done.  Lets walk through all that it does do.

 

  1. Make sure the AutoDiscover control has run.  If not, run it.
  2. Copy all files locally, if needed.  I track a version file to support sending out updates to files if needed.
  3. The lines with the @ symbol at the front are mostly from the CPUU Configuration File Generator.  I prefer to use an echo off at the top vs putting an @ at the front of each line.  I did add “%computername%” and the LogExtended, which were not in the default config.
  4. CPPU runs using the command %run_cmd%.  I also echo that out so I can see it on the screen if I am debugging.
  5. I track the return code of CPUU, The CPUU return code has meaning, but you have to find old documentation to know what that meaning is.  At this point I am tracking it more for fun.
  6. I sift through the CSV files to try to determine if a successful profile update has occurred.
  7. If there was a success then update the autodiscover xml file to use the target.
  8. Move the log files to the central server.

THe SetPreferLocal.cmd is talked about in my next article which you can find here.

Michael