
Sys::Manage::Desktops - Centralised management for desktop computers

use Sys::Manage::Desktops;
my $s =Sys::Manage::Desktops->new(-option=>value,..);
$s->set(-option=>value,..); # See Script Configuration
$s->{-dla} =[{-option=>value,..} # See Assignment Parameters
,...];
$s->Run(@ARGV); # See Command line
perl Script.pl run-mode args
command line may be used (with appropriate run mode) as startup, shutdown, logon, logoff script.
Maintenance command line 'perl Script.pl refresh' is to be used against management computer only.
See Run Modes.

This is a core module for script implementing assignments of commands to be executed on desktop computers.
The Script may define and organise commands or scripts to be executed every startup, logon, logoff, shutdown, as described with -under. Commands may be addressed to particular computers, users, groups. User will not be asked to agree with any startup, logon, logoff, shutdown.
The Script may provide assignments of commands to be executed once, -under 'system' or 'user', within appropriate Run Modes: startup, logon, runapp, agent. Assignments may be addressed to particular computers, users, groups. The assignments to be executed will be listed for user to agree. The assignments will be executed only when user agrees (or -atoy). The execution of assignment may interact with user.
The recurrent and non-recurrent assignments are unified and may be distinguished with -under value: Recurrent assignments: startup, logon, logoff, shutdown. Non-recurrent assignments: 'system', 'user'.
The organising means includes lists of assignments to be previously executed (-doid); computers, users and groups assignments to executed for (-nodes, -users).
The debug and correcting means includes time-based redo of assignment (-doop); agent remote activation and changing periodicity (agent say).
This module does not assumes anything about repository of commands or scripts.
Sys::Manage::Cmd module implements assignments, but synchronous and without interaction to user.

Maintenance or management run modes: query to list assignments; refresh to be used against manager computer only; agent say to be used from manager side.
Desktop or agent run modes may be used against desktop or agent system: startup, logon, agent, runapp, logoff, shutdown.
Scriptic run modes may be used to define or organise appropriate scripts: startup, logon, logoff, shutdown for desktop or agent system. See also startup1 and logon1 Script Modes.
Run modes to check or execute assignments (with appropriate Assignment Modes) on desktop or agent system: startup and agent to execute system assignments; logon and runapp to check system and to execute user assignments.
Windows 95/98: startup executed in logon; agent, logoff, shutdown unimplemented.
Windows 2000/XP: all Run Modes implemented; agent uses 'at' Scheduler commands, may be activated via 'startup period' command line.
Periodical agent operation. system assignments may be executed. user assignments may be checked, if possible.
This item is very platform dependent, see Limitations, Bugs, Problems.
Activate agent from manager via Sys::Manage::Conn(-conn). Default action is 'agent loop'. Immediate actions '-redo' and '-unreg' may be used instead of assignment with -doop => [[-redo=>id] || [-unreg=>id]]. See agent for other actions available, i.e. 'agent stop'.
Execute logoff scripts
Execute logon scripts (-under => 'logon'), then user level assignments (-under => 'user') may be executed. Complete with post-logon scripts (-under => 'logon1').
query runmode|'undef'|'' ?node|'undef' ?user|'undef'
Queries assignments database, displays result. Maintenance run mode.
Maintenance run mode, to be executed against manager only. Refreshes application startup scripts, etc. See also runapp, -mcf, -fresh.
Application startup operation. The Script is called if -fresh from application startup script generated by refresh for -mcf. system and user assignments will be checked, user assignments may be executed.
Execute shutdown scripts
Execute startup scripts (-under => 'startup'), then system level assignments (-under => 'system') may be executed. Complete with post-startup scripts (-under => 'startup1').
Execute startup, start agent, if appropriate.

-under assignment parameter may be used to define startup, logon, logoff, shutdown scripts, and also post-startup and post-logon scripts.
Post-startup scripts will be executed after startup scripts and startup system assignments.
Post-logon scripts will be executed after logon scripts and logon user assignments.
-under => 'logon1'
Post-logon scripts to complete logon process.
-under => 'startup1'
Post-startup scripts to complete startup process.

-under assignment condition may be one of Run Modes, Script Modes, or Assignment Modes.
Assignments under Run Modes and Script Modes are executed at each run of the Script.
Assignments under Assignment Modes are executed once during appropriate Run Modes: startup, logon, agent, runapp.
System level assignments (-under => 'system') will be executed before user level assignments (-under => 'user') if possible (this is platform dependent).
See also Description, Run Modes.
-under => 'system'
The assignment should be executed under system session with considerable permissions. Users profiles may be affected via something like w32regenu.
-under => 'user'
The assignment should be executed under user session with permissions of the user and user's profile available.

Maintenance run mode (refresh) may need special values for: -dirmcf.
The most commonly used parameters are: -banner, -support, -mgrcall, -dirmcf, -dhu, -dhn, -dla, -xnodes, -xusers
=> 30 # sec
User assent timeout during startup and logon. User can agree immediate or agree will be implied past timeout.
=> "Centralised management for desktop computers\n"
Text to display starting execution. See also -lang, -support.
=> empty || {-option => value} || config file name
Configuration for Sys::Manage::Conn object to be used for agent say.
=> undef || {node name => [group names]}
Node groups database, used to match assignment -nodes. If undefined, OS system catalogue may be used and slow performance. If -dla text file, may be reassigned from its -dhn rows when matched. See also -dhu.
=> undef || {user name => [group names]}
User groups database, used to match assignment -users. If undefined, OS system catalogue may be used and slow performance. If -dla text file, may be reassigned from its -dhu rows when matched. See also -dhn.
=> $ENV{SystemRoot} .'\\' .$s->{-prgcn}
|| '/var/' .$s->{-prgcn}
Path to system client/agent registrations of assignments. Each system assignment executed will be registered as a file named according to assignment -id under this path. An assignment may be duplicated also inward -dirmrs.
=> $ENV{AppData} .'\\' .$s->{-prgcn}
|| $ENV{HOME} .'/' .$s->{-prgcn}
Path to user client/agent registrations of assignments. Each user assignment executed will be registered as a file named according to assignment -id under this path. An assignment may be duplicated also inward -dirmru.
=> '%LOGONSERVER%\\NetLogon\\' .$s->{-prgcn} .'-mcf'
Path to menu command files or application startup scripts for -mcf and refresh.
=> undef
|| 'directory' for 'node/id' or 'node-user/id' files
|| file path mask 'directory/[n][-u]/[f][e]'
|| file path mask 'directory/[n]/[f][-ul][e]'
|| ...
File paths for log files on manager. Will be assigned to $ENV{SMLOG} for startup, logon, logoff, shutdown scripts. Subdirectories will be created when required. Path mask may be used with symbols following:
[SignValSign] - value with optional markup signs, value may be:
n - node name,
u - user name,
us - user name or 'sys',
ul - user name or getlogin(),
uw - user name or getlogin() on Windows 95/98, else 'sys',
f - file name (assignment id),
e - file name extension, including '.'
=> undef || see '-dirmls' and '-dirmlu'
File paths to duplicate -dircrs and -dircru registrations to inform manager. Subdirectories will be created when required. See -dirmls and -dirmlu for path mask. Consider synchronisation procedure globing mask to be obtained using replacement of '[f][e]' symbols with '*'. Avoid mixing -dirmls, -dirmrs, -dirmlu, -dirmru files in the same directories or carefully consider naming of files.
=>[{id=>'identifier',...}, ...] | 'file name'
Assignments and commands database to find assignments/commands to be executed. See also Assignment Parameters.
Assignments database may be a perl data structure (array ref) or a text file. Text database format:
# comment row
...
-hostdom=>'all' | 'domain' | /regexp/ # domain for rows below
-domain=>'all' | 'domain' | /regexp/
...
-dhn=>['node name','group name',...] # node groups
...
-dhu=>['user name','group name',...] # user groups
...
-id=>'name' # starting assignment
-attr=>value # parameter of assignment, use perl syntax for value
...
=> domain name
Domain of the user current, see also -user.
=> 0 | 1 | sub{}
Error handler on $SIG{__DIE__}.
=> not exist | 1 | file handle
Switch/handle of additional log file to fill with echo. Related to -dirmls/-dirmlu.
=> host name
Full DNS name of the computer current, see also -node
=> host domain
Domain part of the -host.
=> 'en' | 'ru'
Language of user. See also -banner, -support
=> "perl $0"
Management script call from desktop (agent) systems. To be used for agent and refresh(-mcf, -fresh).
=> node name
Node name of the computer current, may be short of the -host.
=> 'Sys-Manage-Desktops'
Program class name, used to construct another names.
=> ''
Run mode, see Command line, Run Modes.
=> '' | ('mngr' | 'manager') | ('agent' | 'desktop') | 'query'
Script run role to limit Run Modes in Run() to management or maintenance, agent or desktop, query. This may be useful programmatically limiting domain of the Script for parcticular nodes (i.e. w32dcf or w32srv) or users.
=> not exists || 'smtp server name'
=> not exists || ['e-mail address',...]
SMTP server name (for smtpsend) and addressee list to receive errors. May be useful while -yerr.
=> "Call support or press 'Enter' finishing"
Text to display finishing with error(s). See also -lang, -banner.
=> user name
=> is admin user?
=> is console user?
=> is system user?
User current, see also -domain, -node.
=> undef || 'name' || ['name',...]
Exclusive nodes and users assignments should not be executed to.
=> undef || boolean
Assume 'yes' to execute assignments during startup and logon, do not ask user.
=> undef || boolean
Assume 'yes' confirming error messages, do not ask user. May be used along with -smtpeto.

Assignments and commands are organised in assignments database, -dla.
The most used parameters of assignment are: -id, -cmt, -under, -nodes, -users, -do, -doid, -doop.
=> comment string
Description of assignment.
=> empty | sub{}(self, assignment)
Execution condition. More preferred is using -nodes, -users, -doid, -doop.
=> empty | command line | ?! command line
Command line to be executed to apply assignment. Optional starting char may be used to interpret exit code: '?' - success if 0, '!' - success if not 0. Default operation ignores exit code.
Embedded 'do perl-script-file' and 'eval perl-script' commands evaluate file or string given with Sys::Manage::Cmd object in $_. Some of Methods may be called. Optional starting char: '?' - success if true, '!' - success if false, '@' - failure if die. Default operation ignores return value.
=> empty | assignment id | [assignment id,...]
Assignments to be executed before this assignment. Will be listed to user to agree.
=> empty | [[-operation => assignment id],...]
Operations to be executed before (-doop) and after (-doop1) this assignment, but not listed to user. Operations available:
-unreg => id - unregister assignment
-unreg => id, time-string - unregister if registered before time specified
-redo => id, time-string - unregister and execute again, if registered before time specified
-unmenu => id - delete -menu and -mcf items from menu
The -unreg=>(id, 'yyyy-mm-dd hh:mm:ss') and -redo=>(id, 'yyyy-mm-dd hh:mm:ss') operations of -doop may be used effectively in debug procedures. The assignment of this operation only will not be registered, may be executed repeatable with different time specified, will be listed to user only when applicable.
=> empty | assignments overcovering
If this assignment is overcovered by newer assignments. Used only in refresh to include -mgrcall into menu command files for -mcf items.
=> unique identifier
Unique identifier of assignment and name of registration file.
=> empty | true
Requests user to restart computer, breaks execution of the list of assignments.
=> empty | [{param => value,..},..]
Menu items to be creted for execution via command files. The -mcf optional parameter with -id describes the name of command file within -dirmcf. See -menu for another details, refresh and -fresh for usage.
This item is very platform dependent, see Limitations, Bugs, Problems.
=> empty | [{parameter => value,..},..]
Menu items to be created, see also -mcf. 'Name' parameter contains menu item name.
Platform dependent. For Windows see Win32::Shortcut and it's parameters: 'Path', 'Arguments', 'WorkingDirectory', 'Description', 'ShowCmd', 'Hotkey', 'IconLocation', 'IconNumber'. 'Name' may be started with 'Programs', 'Desktop' or 'Startup' subdirectory term. For system assignments will be used 'All Users' menu, for user assignments will be used current user menu.
This item is very platform dependent, see Limitations, Bugs, Problems.
=> empty | 'none' | 'name' | [name,...]
On which nodes (computers) assignment should be executed (except -xnodes). May be used simple names, Windows and DNS domain names, group names from -dhn. Empty value means all nodes; 'none' value allows execution only via -doid or -doop.
=> empty | 'yyyy-mm-dd hh:mm:ss'
Date-time since assignment should be executed.
=> empty | true | false
-uadmin and -ucon Script Configuration values required to execute assignment.
=> empty | 'system' | 'user' | 'startup' | 'logon' | 'logoff' | 'shutdfown'
How to execute assignment: at each startup, logon, logoff, shutdown, or once under user or system session. Empty value treated as system. See also Run Modes, Assignment Modes.
=> empty | 'none' | 'name' | [name,...]
For which users assignment should be executed (except -xusers). May be used simple names, Windows and DNS domain names, group names from -dhu. Empty value means all users; 'none' value allows execution only via -doid or -doop.

May be used in command lines to be executed.
ID of the assignment running.
First and last parts of file path to upload to manager. Obtained using -dirmls or -dirmlu. For startup, shutdown, logon, logoff scripts this is $ENV{SMLOG} broken on $ENV{SMID}.
Registration file path and name, may be used for output of the command. May contain blanks and may need to be quoted in command lines, i.e. cmd.exe /c dir c:\\>>"%SMLOG%". For startup, shutdown, logon, logoff scripts this is log file name formed using -dirmls and -dirmlu.

Useful for Script: new, set, fread, w32dcf/w32srv, Run
Useful for -do => 'do perl-script-file': fcopy, fedit; w32olenew, w32oleget, w32olein; w32registry and w32regenu; w32wmiq and w32wmiqf; acRegDel, acRegRen, meDel; echo, error; and others
Most of methods will die if fail. So, success/failure return value is often not needed.
Assignment call registration. acReg({assignment}) creates registration file using fwrite(), acReg({assignment}, string,...) appends strings to this file.
Assignment call registration delete. Deletes registration file using unlink(), returns 0 if there is nothing to be deleted. Max mtime of the registration file to be deleted may be specified as 'yyyy-mm-dd hh-mm-ss'; registration file will not be deleted if its mtime is greater then specified.
Assignment call registration rename. Renames registration file to new extension using rename(). I.e. acRegRen({...},'.err').
Print header.
Output to user. Alike print().
Failure exit.
Copy files and directories. Options: 'i'gnore errors; 'r'ecurse (default); 's'tat[mtime] to escape superfluous operation; 'v'erbose.
Edit file. Loads file using fread(file), executes editor sub{} to achieve new content, stores content changed using fwrite(file).
File find. Post processing is to see a directory after it's contents. Options: 'i'gnore errors; 'r'ecurse (default).
Directory listing.
Path to temporary directory for Script or assignment. The second parameter is boolean to create directory if not exists. See also ftmp.
Reads file, returns it's content as a scalar.
Execute command or Perl script. Options: 'e'xit code / result consider; 'i'gnore errors; 'v'erbose.
Temporary file for Script or assignment. See also fpthtmp.
Writes strings joined with "\n" to file.
Deletes user shell menu elements (-menu, -mcf) for assignment.
Creates user shell menu elements (-menu, -mcf) for assignment.
Constructor to create new object.
Individual and group names of the computer.
Executes Script Configuration assigned by Script.
Tests if run as manager ('', refresh, query, agent say).
Tests if run as user (logon, logoff, runapp).
Retrieves and sets values of the Script Configuration. $s->{-option} direct access may be used also, but set additionally processes some options.
Individual and group names of the user.
Windows 2000. Access to ADSI objects, see MSDN for details. Example: w32ADSystemInfo->{DomainShortName}
Windows 2000 DC. Path to 'scripts' subdirectory in 'netlogon' share if domain controller. See also w32srv.
Windows 'net use' command clever execution. Options: 'i'gnore errors; 'v'erbose.
Win32. Win32::OLE->new(args) call (may be known also as 'CreateObject'). 'Scripting.FileSystemObject', 'WScript', 'WScript.Shell', 'WScript.Network' objects may be created.
Win32. Win32::OLE->GetObject(args) call.
Win32. Win32::OLE::in(object) call.
Win32. Win32::OLE->LastError() formatted.
Win32. $Win32::TieRegistry::Registry wrapper.
Win32 (Windows 95 not recommended). Enumerates users registry files for sub{} given. Calls sub{} with relevant Win32::TieRegistry subtree for each user profile. May be useful for system assignments affecting user profiles.
Win32. Returns true for Windows server or domain controller. See also w32dcf.
Win32 User Menu definition (start 'm'enu, 'p'rograms, 'd'esktop). w32umnu('mpd') creates a menu item from Win32::Shortcut parameters or items from subdirectory of -w32umnu base path. w32umnu('', sub{}) unlinks items found by ffind, but not mentioned. Additional options may be 'i'gnore errors and 'v'erbose.
Win32::GetOSVersion cached.
Win32. Access to WMI executing query and fetching object(s) via Win32::OLE::in(w32oleget('winmgmts:{impersonationLevel=impersonate}!//node/root/cimv2')->ExecQuery(query | 'select * from class')). Where class may be 'Win32_OperatingSystem', 'Win32_ComputerSystem', etc, see MSDN for details. Examples: w32wmiqf('Win32_OperatingSystem')->{ProductType}, w32wmiqf('Win32_ComputerSystem')->{Model}.

Defines single management server across domain in %SMSERVER% environment variable. Should be placed inside 'Netlogon' share on domain controller.
@rem Defines single management server in the domain.
@rem Smserver.bat - echoes %SMSERVER%.
@rem Smserver.bat command line - executes command line with %SMSERVER% defined.
@rem Use ^%SMSERVER^% notation in command line.
@set SMSERVER=\\servername
@if "%1" == "" @echo %SMSERVER%
@if not "%1" == "" call %*
Script implementation. Should be placed inside 'Netlogon' share on domain controller.
#!perl -w
my $script =Win32::GetFullPathName($0);
my $domain =eval('use Net::Domain; Net::Domain::hostdomain')
||Win32::DomainName() ||$ENV{USERDOMAIN};
my $spath =$script =~/^(.+?)[\\\/][^\\\/]+$/
? $1
: $ENV{LOGONSERVER}
? "$ENV{LOGONSERVER}\\NetLogon"
: "\\\\$domain\\NetLogon";
eval{require ("$spath\\Desktops.pm")}
||eval{require Sys::Manage::Desktops}
||die('Cannot load Sys::Manage::Desktops');
my $s=Sys::Manage::Desktops->new(-errhndl=>1);
if (!$ENV{SMSERVER} # %SMSERVER% read
|| ($ARGV[0] && ($ARGV[0] =~/^(?:startup)/))) {
$s->fread("$spath\\SMServer.bat") =~/set\s*SMSERVER\s*=\s*([^\r\n\s]+)/
? $ENV{SMSERVER} =$1
: $s->error("Missing %SMSERVER%\n");
}
if ($s->w32dcf()) { # DC - Run on Manager
$s->set( -mgrcall=> "perl.exe \\\\$domain\\NetLogon\\" .$s->{-prgsn}
,-dirmcf => "$ENV{SMSERVER}\\SMShare"
);
}
else { # Agent Run
$s->set( -mgrcall=> ($ENV{PERLPATH}||'') ."perl.exe $script"
,-dirmcf => "%SMSERVER%\\SMShare"
);
}
$s->{-runrole} =$s->w32srv() # Limit agent to desktops
? 'mngr' : '';
$s->{-dla} ="$spath\\smserver.txt"; # Assignments Database
$s->Run(@ARGV); # Evaluate $ARGV[0] operation
To configure startup and logon scripts.
Security: user, computer$: Apply
Options:
Computer Configuration / Windows Settings / Scripts
Startup = ..\..\..\..\..\Scripts\SMServer.bat perl ^%0\..\smserver.pl startup agent
Computer Configuration / Administrative Templates / System / Scripts
Run Startup Scripts Visible = +
Maximum wait time for Group Policy scripts = (default=600 sec)
User Configuration / Windows Settings / Scripts
Logon = ..\..\..\..\..\Scripts\SMServer.bat perl ^%0\..\smserver.pl logon
User Configuration / Administrative Templates / System / Scripts
Run Logon Scripts Visible = +

- Limitations, Bugs, Problems
This module is implemented and tested with Perl 5.6.0 and 5.8.8 on Windows 2000/XP.
Implementation predominantly for Windows desktops, espacially
-menuand-mcf,agent, 'w32' functions.Linking
systemanduserassignments with-doidor-doopis undesirable.Mixing
systemassignments with-userscondition is undesirable, however-nodescondition may be inuserassignments.Startup or logon scripts may be liable to timeouts or may became hidden from user, so response timeouts used interacting with user.
See also at the top of the source code.

New -uadmin and -ucon Assignment Parameters. Changed -do => 'do perl-script-file' to be alike frun. New -do => 'eval perl-script'.
Defaults of nnames() and unames() extended with -host and -hostdom. -hostdom and -domain in the -dla text file may be /regexps/.
New -echof.
Extended internal usage of echo().
-host may be Win32::NodeName if not Sys::Hostname::hostname.
Improved error messages from fpthmk().
New w32ver(), corrections for Windows NT.
Extended fcopy(). Documented nnames() and unames(). New runmngr(), runuser(), frun(), ffind(), w32nuse().
Added -hostdom =>'all' | 'domainName' markup for -dla text file.
Publishing 0.59.
Opening of upload directory added to prevent network connection lose on Windows.
Publishing.
Testing...
Documentation written.
Started.

This is free software; you can use redistribute it and/or modify it under the same terms as Perl itself.

Andrew V Makarow <makarow at mail.com>, for zhenya