﻿
LwL.ProfileUnity.Client.CompactVHD is a program to reduce the amount of disk space consumed by 
VHD and VHDX files when using ProfileUnity's ProfileDisk option.  It can
either compact a single file (when the "/VHDFile" option is used), or 
all files in/under a given directory (when the "/VHDDir" option is used).

It is expected that the program will typically be run from the ProU server,
whereas the ProfileDisk VHDs will typically be stored on a file share on the
domain controller, or perhaps elsewhere in the network.  In any case, the key
is that this program is extremely I/O intensive, and network file access 
tends to be slow - so the program copies the files from the network share to 
a working directory (via the "/WorkDir" option, which should refer to a local 
directory, ideally SSD), does the most I/O-intensive operations there, and 
then copies the results back out to the network storage where ProfileDisk 
files normally live.

Sample use:

    LwL.ProfileUnity.Client.CompactVHD.exe /VHDDir "\\DC01\Share\ProfileUnity" 
                                           /LogLevel Info 
                                           /WorkDir "C:\Work" 
                                           /LogPath "C:\Work" 


Options:

/AcceptEULA - Required parameter (if not supplied, the program will tell
              you where the EULA is and suggest you read it)

/Quiet  -   Don't display a popup window during execution 
            Note: if running via a command line you will still see log data depending on the LogLevel set

/LogName - overrides the default logfile (not generally needed)

/LogLevel - overrides the default logging level.  For this program, "Info" 
            is recommended

/LogPath - provides an alternate directory for log files.  The default
           location is %TEMP%\LwL.ProfileUnity.Client.CompactVHD.

/VHDFile - fully-qualified path to a single VHD(x) file.  Only this one file 
           will be compacted. Note that you must specify 
           either /VHDFile or /VHDDir, but not both.

/VHDDir - path to the directory that contains all VHD(x) files, typically 
          something like “\\server\share”.  All VHDs in that path (except 
          parent/child disks) will be compacted.  Note that you must specify 
          either /VHDFile or /VHDDir, but not both.

/StartsWith - Gives one or more ranges that the file must start with, such 
              as “/StartsWith A-C”.  Note that it’s actually looking at the 
              part of the path beyond the “/VHDDir”, so whatever letters come 
              next (typically the username) are what it’s looking at.  

/WorkDir - Provides a work directory, ideally on local SSD storage.  All files 
           for each VHD being compacted will be put in subdirectories of this 
           directory.  If a compaction completes successfully, the subdirectory 
           will be deleted - but if a compaction fails for some reason, the 
           subdirectory (which also contains VHD log files that might be useful 
           for problem diagnosis) will remain.  The default is %temp%\LwL.ProfileUnity.Client.CompactVHD.

/EraseBK - The program renames the old VHD(x) files as VHD(x).BK, but that
           leads to large amounts of space being taken up by the backup files.  
           Running the compactor with “/EraseBK” will delete those BK files.

/EraseBKInline - Deletes the VHD(x).BK right after each successful compaction. Note that 
                 .BK files exist for a good reason!  If you delete them but something
                 (silently) went wrong during the compaction process, your out of luck!

/ConvertTo VHDX - Converts VHD files to VHDX files (or vice versa)

/SMTPServer - The program can send an email with a summary of what it did; 
               this gives the SMTP server to use for sending that email.

/SMTPPort - Likewise for the port.  This is generally not needed, unless 
            the SMTP server is running on a non-standard port

/SMTPSSL  - True or False (some SMTP servers require SSL, others prohibit it)

/SMTPUser - UserID for SMTP server (note that some servers require this to 
            match the "/MailFrom" address)

/SMTPPass - Password for the above userid.  This is assumed to be cleartext,
            but if you want to provide an encrypted password, just prefix it
            with "ENCRYPTED:" 

/SetSMTPPass xxx - Takes the given cleartext password, encrypts it, adds an
                   "ENCRYPTED:" prefix, and and writes it into the 
                   LwL.ProfileUnity.Client.CompactVHD.exe.config file

/MailTo - one or more (comma-separated) email addresses that the summary 
          should be sent to

/MailFrom - the email address that the email will appear to have come from

/MaxThreads - the maximum number of simultaneous compactions (the number may 
              be reduced, based on available space on the /WorkDir drive).  
              Note that the process is heavily I/O-bound, and testing seems 
              to show that running 2 or more simultaneous compactions actually 
              slows it down overall, rather than speeding it up.  As a result, 
              the default is "1", and use of this option is discouraged.

/MinDiskMB 500 - any VHD(x) files below this size will be skipped. The default  
                 is 500MB.

/MinSaveMB 0 - specifies the minimum savings required to be worth doing.  The
               default is zero, but that can result in the creation of a .BK
               file of many gigabytes just to save a few megs.  By setting
               this parameter, you can tell it to skip the compaction (and
               thus the creation of the .BK file) if the savings are minimal.

/MaxHours X - Stops the process shortly after X hours. It is recommended that
              if you want to schedule a job to run for (say) 8 hours, you 
              should set this parameter to 7 hours, so that the program
              will stop cleanly instead of getting interrupted. You can
              use fractional hours (e.g. "/MaxHours 0.25" = 15 mins), though 
              that's probably more useful in testing than in the real world. 
              The default is 0, which means "no limit".

/BackupPath <dir> - By default, the program will save the user's original 
                    vhd(x) files as vhd(x).BK files in the same directory,
                    just in case anything goes wrong and you need to restore
                    them (by simply renaming them w/out the BK extension).

                    However, that means that disk space consumed on the disk
                    containing the VHD(x) will go UP, not down, until the
                    files are erased with the "/EraseBK True" option (which
                    you shouldn't do until you're comfortable that there are
                    no issues).

                    Optionally, you can specify an alternate location to
                    store the backup files (perhaps on less expensive disks),
                    so that the disk space consumed on the main drive goes
                    down.  Of course, this does means that restoring the data 
                    will involve copying the files back, rather than just 
                    renaming them.
                    
                    One slight complication is that it's possible that two 
                    different VHD files in different directories have the same 
                    filename. Normally this isn't a problem, because the BK
                    files goeinto the same directory as the VHD file - but 
                    with the /BackupPath option, they all go into a single
                    directory, and name collisions are possible.  To reduce
                    the chances of this, each filename is suffixed with 8
                    hex characters calculated from the original filename. If
                    you need to copy the files back for some reason, you'll
                    have to manually strip off the suffix.  And if you do
                    have two files that have the same name (except for
                    the suffix), you'll have to figure out which one goes
                    where based on other criteria: the size, contents, etc.
                    
                    The "/EraseBK True" option will use the /BackupPath,
                    if specified, as the location in which backup files
                    should be erased.

/MinDaysSinceLastCompaction 30 - By default, all VHD(x) files will be compacted 
            (subject to /MinDiskMB and /MaxHours, of course) - but that's probably 
            overkill if the disk was just compacted a few days ago. With this 
            option, you can tell it to skip any VHD(x) files that were last 
            compacted less than X days ago.  The default is 0, which means 
            "no limit".

/GlobalStats false - By default, summaries of the compaction effectiveness
                     will be uploaded to the Liquidware globals stats server,
                     and lifetime totals will be displayed in the log.
                     However. this behavior can be turned off by using
                     this option.

/IgnoreFailedParentChecks true - VHDs can be standalone disks, or they can be 
                     "parent" or "child" disks.  If something is a parent disk, 
                     and it gets compacted, the child disk will become UNUSABLE.

                     To guard against that, the program checks for parent/child
                     disks before starting compaction, and refuses to compact
                     parent disks.  HOWEVER, there's no way to detect a parent
                     disk (there's literally not a single bit different in the 
                     VHD file) - instead, the program must scan all (potential)
                     CHILD disks, to see what disks they might be children of.

                     If even a single disk cannot be scanned (due to permission
                     errors or the like), the entire process must be aborted,
                     because the unscannable disk could, in principle, be a 
                     child of ANY disk - meaning the only safe thing to do is
                     to stop immediately.  (NOTE: if this doesn't make sense,
                     please re-read the above paragraph until it does.  It's 
                     critical to understand why that's true, but all too easy
                     to misunderstand it).

                     Alas, people don't like that - they keep thinking that 
                     it should be able to skip the offending disk and compact
                     everything else.  So there's a new option that will let
                     the program continue despite being unable to check one
                     or more disks.  
                     
                     IMPORTANT: USE OF THIS OPTION COULD CAUSE DATA LOSS
                     IF THERE ACTUALLY ARE PARENT/CHILD DISKS!

                     It is recommended that this option NOT be used unless 
                     there are no parent/child disks. For example, if you 
                     haven't set up multi-session disks, there should be no 
                     parent/child disks.

/AllowMultiple true - Allows multiple instances of this program to run at the same time.
                     Note: be careful using this, as there are reasons it is
                     defauled to false (see PUNC-1393 Program termination causes VHD 
                     files to be left over in past Work folders, and sometimes to 
                     remain mounted to system)

