﻿Change notes
============

WPKG Version: 0.10.12-redesign
Author:     : Rainer Meier <skybeam (at) users.sourceforge.net>
Date        : 2007-11-19

Changes/fixes visible to the user:

Summary:
- IP-based profile selection.
- Logfile writing with configurable log level (see /logfilePattern, /logLevel and /log_file_path
- Profile based log level: <profile logLevel="<level>" /> attribute added.
- Forced zombie removal added.
- Support for package revision in the form of x[.y[.z[...]]] added.
- Fixed Bug 29: XML files with syntax errors are ignored, no immediate exit any more.
- Added support for reboot='delayed' flag to package nodes.
- Added /config switch to specify location of config.xml.
- Fixed Bug 40: Added workdir='path' attribute to command nodes.
- Fixed Bug 81: Added /ignoreCase switch which allows WPKG to work case-insensitive.
- Fixed Bug 53: Allowing multiple profiles per host.
- Added support for installdate/uninstalldate attribute in profile package-references.
- Added upgrade-before-remove.
- Package installation failure does not force immediate quit.
- Print total number of packages within /query:a
- Package removal in reverse-priority order
- Exit node allows code='any' to match any exit code.
- Changed registry equals check to match expanded values as well.
- Re-organized usage help screen.
- Fixed Bug 12: Checking for registry keys is now possible.
- Fixed Bug 5: Notification even if nothing to do
- Fixed Bug 52: Duplicated wpkg.xml nodes on /upgrade:<package>
- Fixed Bug 57: Not installing packages whose dependencies failed.

Bugs fixed:
Bug 5
Bug 12
Bug 29
Bug 40
Bug 52
Bug 53
Bug 57
Bug 81

NEW: Allowing matching of IP-addresses within the profile name now. The
	 format has to be specified as follows:
	 <start>[-<end>].<start>[-<end>].<start>[-<end>].<start>[-<end>]
	 examples:
	 192.168.1.1
	 192.168.1.1-254
	 192.168.1-5.20-50

	 This feature has been on the TODO list for quite a while.

	 Re-Used code from scanUninstallKeys() to retrieve IP address from the
	 registry. According to my knowledge there is no direct interface within
	 WScript to access the local IP adress(es).

NEW: Introduced ability to write a log file to a specified directory. This
	 allows administrator to have clients writing a log file to a shared
	 directory to trace client execution.

NEW: Log-file naming pattern is configurable in order to allow having one
	 log file per client, one log file per day/hour/minute...

NEW: Configurable log level allows administrators to change level of log
	 detail within config.xml (or overridden by command line switch).
	 Note: Log level detail is not coupled to the /debug flag. It is possible
	 to write a full debug log even if the /debug flag is not set.

NEW: Added support for profile-based log level. You might use a profile node
	 as follows:
	 <profile id="profileID" logLevel="0xFF">
		...
	 </profile>
	 If not specified it keeps the default log level. So final evaluation
	 priority is as follows:
	 - config.xml
	 - command line parameter (/logLevel:<#>)
	 - profile-specific logLevel

NEW: Zombie packages will be removed from the local package database even if
	 locally stored uninstall string fails. Except if the package is still
	 referenced in the applying profile. In such a case a message about
	 message about inconsitency between profiles and the package database is
	 printed. This makes sure that a package does not generate a recurring
	 error on each boot (when using wpkg-service) in case the package has
	 been completely removed from the server.
	 In case you like to disable this have a look at the /noforcedremove
	 switch.

NEW: Using versionCompare() now to compare versions of packages. This allows
	 usage of string representation of revision attribute on each package.
	 Currently wpkg_web supports just integer values but this could be
	 changed. Therefore packages can now have versions in the form of
	 <version>[.version[.version[...]]]

NEW: WPKG does no longer stop parsing of XML files within folders in case of
	 syntax errors. It just prints an error-severity message that the file is
	 broken and and proceedes with the next file. In case /quitonerror is
	 enabled it still exits immediately on XML load error.
	 Fixes Bug 29.

NEW: Added possibility to customize user messages (notifications) within
	 config.xml. This change was proposed by Falko Trojahn and extended by
	 myself. The idea is to localize at least the notification messages
	 since they have to be read by the machine user. There are currently no
	 intentions to localize all info/warning/error/debug messages. However
	 it would be possible - but with a lot of effort and with quite small
	 benefit.
	 I already inserted translated messages for english and german LCIDs.
	 French has been prepared as well (LCIDs) but the messages were not
	 translated yet since my french might be funny to read but not make
	 much sense ;-)

NEW: The reboot=true attribute on an exit code forces an immediate reboot.
	 Unfortunately all following commands are skipped then. Sometimes
	 (maybe even more often) you might like to just set the package reboot
	 flag depending on a command exit code. I introduced the support of
	 reboot='delayed' within the command nodes. This allows to schedule a
	 reboot instead of immediately executing it. The effect is the same
	 as setting reboot='true' on package level (reboot after executing
	 all comands. However it allows you to leave reboot='false' on package
	 level and schedule a reboot based on command exit codes.

NEW: Added /config:<path> parameter which allows to specify an alternative
	 configuration file location.

NEW: Allows specifying of workdir='%WINDIR%\path\to\dir' attribute in
	 package command nodes to specify the execution working directory.
	 e.g.
	 <install cmd='msiexec /i (path to msi)' workdir='%WINDIR%\system32' />
	 Note: This works for install, upgrade and remove nodes.
	 Fixes Bug 40.

NEW: Added /ignoreCase switch which allows to disable case sensitivity of
	 packages and profiles. Therefore you can assign the package "myapp" to a
	 profile while only a package "MyApp" is defined within the packages.
	 Note that this change requires modifying of the package/profile/host nodes
	 read from the XML files. All IDs are converted to lowercase.
	 Please note that this is a kind of one-way switch. Removing the switch
	 later will cause all packages which use uppercase characters to fail
	 looking up the local package node (which is stored in lowercase only).
	 Fixes Bug 81.

NEW: Implemented change to allow multiple profiles to be specified within a
	 host node (hosts.xml). The entries need to have the following format:
	 <host name='hostname' profile-id='main-profile'>
		<profile id='profile1' />
		<profile id='profile2' />
	 </host>
	 The legacy "profile-id" is still used and preferred if you refer just
	 to one single profile. However it is required to specify at least one
	 valid profile which can be resolved within profiles.xml.
	 WPKG will quit immediately if no profile can be resolved. Note that
	 host definitions in the form of
	 <host name='hostname' profile-id='main-profile' />
	 are still allowed and preferred. Additionally the following is allowed
	 as well:
	 <host name='hostname'>
		<profile id='profile1' />
		<profile id='profile2' />
	 </host>
	 as long as at least one valid profile is referenced.
	 Please note: If you use [PROFILE] within the logfile-template the names
	 of all referenced profiles are concatenated in the form of
	 <profile>[-profile[-profile]]
	 Fixes Bug 53.

NEW: Added ability to install packages by date.
	 To use this feature an install/uninstall date has to be specified within
	 the package node of the profile. Example:
	 <package package-id="pkg" installdate="<date>" uninstalldate="<date>" />

	 Note that a package can be referenced several times within different
	 profiles. Each profile can specify its own install/uninstall date for a
	 specific package (that's why it is not a property of the package itself).

	 In case a host has multiple profiles assigned and the package is
	 referenced from multiple profiles WPKG will evaluate all package
	 references. If one of the references specify that the package has to be
	 installed (or not date-range is specified at all), the package will be
	 applied.

	 Date is parsed in ISO 8601 format.
	 See <http://www.w3.org/TR/NOTE-datetime>.
	 Generic format example:
		"YYYY-MM-DD hh:mm:ss"
	 Valid date examples:
		(the following dates are all equal if ceil is set to false)
		"2007-11-23 22:00"			(22:00 local time)
		"2007-11-23T22:00"			(Both, "T" and space delimiter are allowed)
		"2007-11-23 22:00:00"		(specifies seconds which default to 0 above)
		"2007-11-23 22:00:00.000"	(specifies milliseconds which default to 0)
	 It is allowed to specify the timezone as well:
		"2007-11-23 22:00+01:00"	(22:00 CET)
		"2007-11-23 21:00Z"			(21:00 UTC/GMT = 22:00 CET)
		"2007-11-23 22:00+00:00"	(21:00 UTC/GMT = 22:00 CET)

	 If 'ceil' is set to true then unspecified date components do not fall back
	 to "floor" (basically 0) but will be extended to the next value.
	 This allows easy comparison if the current date is within a parsed "!ceil"
	 date and a parsed "ceil" date.
	 Examples:
	 ceil=false:
		"2007-11-23"	=> "2007-11-23 00:00:00"
		"2007-11"		=> "2007-11-01 00:00:00"
	 ceil=true:
		"2007-11-23"	=> "2007-11-24 00:00:00"
		"2007-11"		=> "2007-12-01 00:00:00"

	 TIMEZONES:
	 As specified by ISO 8601 the date is parsed as local date in case no
	 time zone is specified. If you define a time zone then the specified time
	 is parsed as local time for the given time zone. So if you specify
	 "2007-11-23 22:00+05:00" this will be equal to "2007-11-23 18:00+01:00"
	 while "+01:00" is known as CET as well. The special identifier "Z" is equal
	 to "+00:00" time zone offset.

	 Usually you will not specify any time zone at all since you might have a
	 package installed at 08:00 local time rather than installing it at
	 08:00 in UTC+1 time zone while it is installed at 15:00 in UTC+8 time
	 zone (when specifying 07:00Z or 07:00+00:00 install time).

	 Specifying an empty string as dateString is allowed and will results in
	 returning the first of january 00:00 of the current year (ceil=false) or
	 first of january 0:00 of the next year (ceil=true).

	 This implements a feature on the TODO list.

MOD: Upgrading to the latest package version before removing a package
	 (if package is still available on server). This allows administrators
	 to fix broken uninstall commands by supplying a new package with fixed
	 commands. WPKG will now first do the upgrade and then execute the
	 uninstall commands.

MOD: Does not stop execution in case a package fails installation except if
	 /quitonerror flag is set.

MOD: Sorting setting nodes before saving settings. This allows easier diff
	 of XML files on server. See
	 <http://wpkg.org/Viewing_software_installed_on_workstations>
	 for more information.

MOD: Error in case of failed XML file read is now printed in one message
	 instead of splitting it to several event log entries.

MOD: Modified install procedure. In case a package is not within the local
	 settings it checks if the package checks return true (package
	 installed) before it is installed. This was done to prevent re-
	 installing all packages in case of a lost local wpkg.xml.
	 Unfortunately this introduces a small chance that in case a new version
	 is added to the package database AND the local wpkg.xml is deleted AND
	 the check for the new package yields true for an old installation as
	 well that the new package does not get installed. However in any case
	 the next upgrade will fix that.
	 I still added the changes since the advantages wight much heavier than
	 the disadvantages of re-installing every package in case of lost local
	 database.
	 NOTE: This will not prevent packages without checks to be re-installed
	 if no package checks are provided.

MOD: Query all packages will now print the total number of packages as well.

MOD: Changed "notify" package attribute handling. Now by default (if
	 attribute is missing) a notification is sent. This allows disabling of
	 notification for a specific package by setting the notify="false"
	 attribute.
	 NOTE: It is still possible to disable notifications for ALL packages
		   by using the /nonotify switch or disable notify within config.xml.

MOD: Packages are removed in reverse order (regarding priority).
	 Note: Due to the new upgrade-before-remove feature all packages
	 scheduled for removal are upgraded first. This upgrade is done in
	 respect to the priority (highest priority first).
	 Fixes Bug 24.
	 Fixes Bug 51.

MOD: Exit node allows to specify code='any' now which matches any exit
	 code. Specific exit codes still takes precedence. The user might
	 specify the reboot=true/false/delayed flag for code='any' nodes as
	 well.

MOD: Registry 'equals' conditions allows now to include variables like
	 "%SystemRoot%". WPKG will now check if the registry value contains
	 the given string. If it does not match it expands the string and
	 checks again.
	 Fixes Bug 47.

MOD: Re-organized usage help output. Now structured into three chapters:
	 - package operations
	 - optional parameters
	 - testing parameters
	 This hopefully helps to prevent scaring new users with lots of
	 parameters while most of them are optional anyway.

FIX: Implemented fix for Bug 12 - getRegistryValue() returns the key default
	 value if a path to a key is specified. If the "(default)" entry is not
	 set it returns an empty string (""). Still returns null in case no such
	 registry entry could be located (neither key nor value).
	 This allows defining a check for a registry KEY (not only for values).

FIX: Notification about package installation is sent only in case an
	 installation actually takes place.

FIX: No change here but the redesign already fixes Bug 52 (multiple wpkg.xml
	 entries for one package when using /upgrade:<package>
	 Fixes Bug 52.

FIX: No change here but the redesign should fix Bug 54 (dependency
	 installation does not work).
	 Fixes Bug 54.

FIX: No change here but the redesign should fix Bug 57 (not installing
	 packages whose dependencies failed to install).
	 Fixes Bug 57.



Internal changes/fixes (usually invisible to the end-uer):

NEW: Added methods to read the system locale and to read the value of a
	 corresponding localized string from a string ID within config.xml.

MOD: Unified logging, info(), dinfo(), warning() and error() use the log()
	 method now which can handle the output in one single place.

MOD: query*() methods now rely on the same code. Unifies output formatting
	 and siplifies maintenance.

MOD: Saving settings XML file just once (on exit) instead of several times.

MOD: installPackage() now acts more intelligent and detects if a package
	 needs to be installed, upgraded or skipped. It also takes into account
	 the package execution flag ("always" or "once"). Therefore the
	 upgradePackage() and executeOnce() methods which mainly contained
	 duplicated code are removed. Just call installPackage() for each
	 package which applies to the system no matter if it is already
	 installed or not.

MOD: Removed some redundant code.

MOD: Lots of code reformatting and restructuring. The target was to create more
	 documented and portable code. XML node handling is now handled within
	 getter (get*) and setter (set*) functions. This eases handling of
	 attributes without having to write hard-coded XPATH expressions within the
	 code.

MOD: Splitted script parameter evaluation and initialization.

MOD: Lots of comments, function documentation blocks and debug output added.

MOD: Removed duplicated usage-description (file-header, showUsage()) which
