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.
- It runs best if it is run locally and not from a share.
- It runs slow if you write the output log to a share (e.g. write the log locally).
- 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).
- 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.
- Make sure the AutoDiscover control has run. If not, run it.
- Copy all files locally, if needed. I track a version file to support sending out updates to files if needed.
- 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.
- CPPU runs using the command %run_cmd%. I also echo that out so I can see it on the screen if I am debugging.
- 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.
- I sift through the CSV files to try to determine if a successful profile update has occurred.
- If there was a success then update the autodiscover xml file to use the target.
- Move the log files to the central server.
THe SetPreferLocal.cmd is talked about in my next article which you can find here.
Michael