Win32API::Net - Perl interface to the Windows NT LanManager API account management functions. |
UserModalsGet()
UserModalsSet()
LocalGroupAddMember()
LocalGroupDelMember()
LocalGroupSetMembers()
Win32API::Net - Perl interface to the Windows NT LanManager API account management functions.
use Win32API::Net;
As of version 0.08 of this module, the behaviour relating to empty strings in input hashes has changed. The old behaviour converted such strings to the NULL pointer. The underlying API uses this value as an indication to not change the value stored for a given field. This meant that you were not able to clear (say) the logonScript field for a user using UserSetInfo().
The new behaviour is to leave the string as an empty C string which will
allow fields to be cleared. To pass a NULL pointer to the underlying
API call (and thus, to leave the field as it was), you need to set the
corresponding field to undef
.
WARNING: THIS IS AN INCOMPATIBLE CHANGE. EXISTING SCRIPTS THAT RELIED ON PRIOR BEHAVIOR MAY NEED TO BE MODIFIED.
Win32API::Net provides a more complete wrapper for the account management parts of the NT LanManager API than do other similar packages. Most of what you can achieve with the native C++ API is possible with this package - albeit in a more Perl like manner by using references to pass information to and from functions.
For an understanding of the environment in which these functions operate see DATA STRUCTURES.
The following groups of functions are available:
All functions return 0 on failure and 1 on success. Use the
Win32::GetLastError()
function to find out more information on why a
function failed. In addition, some functions that take a hash reference
to pass information in (e.g. UserAdd()
) have a last argument that will
allow more detailed information on which key/value pair was not properly
specified.
References to hashes and arrays are used throughout this package to pass information into and out of functions.
$href = \%someHash; UserAdd(server, 2, $hRef);
Or more directly:
UserAdd(server, 2, \%someHash);
$aref = \@someArray; UserEnum(server, $aref);
Or more directly:
UserEnum(server, \@someArray);
Please note: Any *Get*()
or *Enum()
operation will first clear the
contents of the input hash or array being referenced.
See EXAMPLES and the test.pl script for examples of usage.
Most of the functions in the underlying API allow the programmer to pass
specify at runtime the amount of information that is supplied to the
function. For example, the NetUserGetInfo()
call allows the programmer to
specify levels of 0, 1, 2, 3 (and others). Having specified this level, the
function returns a structure that will contain different fields. For a
level 0
, the function returns a structure that has only one field. For a
supplied level of 1, the function returns a structure with 8
fields. The
programmer needs to know in advance what fields should be provided or will
be returned for a given level. This mechanism works very will since it
effectively overloads functions without having to use different function
prototypes. Perl provides better higher level data structures in the form
of arrays and hashes. This package uses hashes as the means to pass these
variable size structure into and out of functions.
For any function that takes a reference to a hash as input, the programmer is expected to provide appropriate keys and corresponding values as well as the level parameter. The called function will then takes the values out of the supplied hash and build the appropriate structure to pass to the underlying API function.
For any function that takes a reference to a hash to receive output, the function will first clear any keys an corresponding values in the supplied hash. It will call the underlying API call and will then return in the hash any keys and values that are applicable at the requested level.
Example:
The UserGetInfo()
can takes a number of levels. If called with level 0
the supplied hash will, on return from the function, contain a single key
and value - namely name/requested-users-name. If called with a level
of 1
the supplied hash will, on return from the function, contain 8 keys
and values. The returned keys are name, password
, passwordAge
,
priv
, homeDir
, comment
, flags
, scriptPath
. See
USER INFO FIELDS for more information on what these represent.
By default, Win32API::Net exports no symbols into the callers namespace. The following tags can be used to selectively import symbols into the main namespace.
:User
User*()
functions.
See NET USER FUNCTIONS.
:Get
Get*()
functions.
See NET GET FUNCTIONS.
:Group
Group*()
functions.
See NET GROUP FUNCTIONS.
:LocalGroup
LocalGroup*()
functions.
See NET LOCAL GROUP FUNCTIONS.
The User*()
functions operate on NT user accounts.
Administrator or Account Operator group membership is required to successfully execute most of these functions on a remote server or on a computer that has local security enabled. Administrator privileges are required to add an Administrator Privilege account. There are some exceptions to this whereby a user can change some of their own settings where these don't conflict with 'administrative information' (e.g. full name).
The server
field can be the empty string, in which case the function
defaults to running on the local computer. If you leave this field blank
then you should ensure that you are running the function on a PDC or BDC
for your current domain. Use the support function GetDCName()
to find out
what the domain controller is, should you not be running this on the PDC.
All functions in this section are 'DOMAIN functions'. This means that,
for example, the UserGetLocalGroups()
function actually lists the
domain's local groups of which the named user is a member.
The following functions are available.
Add a new user account. The user name is taken from the name
-key's
value in the supplied hash.
server
- Scalar Stringlevel
- Scalar Inthash
- Hash Referencelevel
.
error
- Scalar Int
Changes the password for user
. If the policy of the machine/domain
only allows password changes if the user
is logged on then the user
must be logged on to execute this function. With Administrator or Account
Operator privilege you can use this function to change anyone's password,
so long as you know the old password.
server
- Scalar Stringserver
on which to change the password.
user
- Scalar Stringuser
whose password is being changed.
old
- Scalar Stringuser
.
new
- Scalar Stringuser
.
Deletes the specified user
account. Administrator or Account Operator
privilege is required to execute this function.
server
- Scalar Stringserver
on which to delete the user
.
user
- Scalar Stringuser
account to delete.
Enumerates all the accounts on server that satisfy filter
. Unlike the
NetUserEnum()
function in the API, this function does not allow you
to specify a level (internally it is hardcoded to 0). In Perl it is
trivial to implement the equivalent function (should you need it) - see
Example 1.
server
- Scalar Stringserver
on which to enumerate the accounts satisfying filter
.
array
- Array Referenceserver
whose
accounts match filter
.
filter
- Scalar Int (optional)FILTER_NORMAL_ACCOUNT
is used.
Get the global groups for which user
is a member. It returns the group
names in array
. Unlike the NetUserGetGroups()
function in the API,
this function does not allow you to specify a level (internally is
hardcoded to 0). In Perl it is trivial to implement the equivalent function
(in the unlikely event that you might need it).
server
- Scalar Stringserver
from which to get the groups of which user
is a member.
user
- Scalar Stringuser
whose group membership you wish to examine.
array
- Scalar Stringuser
belongs.
Returns the information at the specified level
for the named user
in hash
.
server
- Scalar Stringserver
from which to get the requested information about user
.
user
- Scalar Stringuser
whose information you want.
level
- Scalar Inthash
- Hash Reference
Gets the names of the local groups of which user
is a member. Unlike
the NetUserEnum()
function in the API, this function does not allow you
to specify a level. Since the underlying API restricts you to level 0 there
really isn't any need to include it...
server
- Scalar Stringuser
is a member.
user
- Scalar Stringuser
whose local group membership you wish to enumerate.
array
- Array Referenceuser
belongs.
flags
- Scalar Int <em>(optional)</em>Win32API::Net::LG_INCLUDE_INDIRECT()
or 0. if flags
is
omitted, the function internally uses 0. Specifying LG_INCLUDE_INDIRECT()
will include in the list the names of the groups of which the user
is
indirectly a member (e.g. by being in a global group that is a member of a
local group).
This field can take no other values.
UserModalsGet()
This function is not currently implemented.
UserModalsSet()
This function is not currently implemented.
Sets the (global) group membership for user
to the specified groups.
Unlike the API function NetUserSetGroups()
, this function does not take a
level
parameter (mainly because this option is largely redundant).
server
- Scalar Stringserver
on which you wish to set the group membership for user
.
user
- Scalar Stringuser
whose group membership you wish to set.
array
- Array Referenceuser
s
membership of.
This function will fail if any of the group names specified do not exist.
Sets the info for user
according to the information contained in hash
for level
(see USER INFO LEVELS).
server
- Scalar Stringserver
on which you wish to change the info for user
.
user
- Scalar Stringuser
whose info you wish to change.
level
- Scalar Intuser
- although this may not be
supported in future...
hash
- Hash Referencelevel
(see USER INFO LEVELS).
error
- Scalar Inthash
were not properly
specified. See USER FIELD ERRORS for more information about what
values can be returned in this field.
The Group*()
functions all operate only on global groups. To modify
local groups, use the corresponding LocalGroup*()
functions.
Administrator or Account Operator group membership is required to successfully execute most of these functions on a remote server or on a computer that has local security enabled.
The server
field can be the empty string, in which case the function
defaults to running on the local computer. If you leave this field blank
then you should ensure that you are running the function on a PDC or BDC
for your current domain. Use the support function GetDCName()
to find out
what the domain controller is, should you not be running this on the PDC.
The following functions are available.
Adds the specified group.
server
- Scalar Stringserver
on which to add the group.
level
- Scalar Stringlevel
of information contained in hash
. This can be one of 0, 1, 2
or 3. See GROUP INFO LEVELS.
hash
- Hash Referencelevel
.
error
- Scalar Inthash
was not properly specified.
See GROUP FIELD ERRORS for more information about what values can be
returned in this field.
Adds the specified user
to the specified group
.
server
- Scalar Stringserver
on which to add the user
to group
.
group
- Scalar Stringgroup
to add the user
to.
user
- Scalar Stringuser
to add to group
.
Deletes the specified global group.
server
- Scalar Stringserver
on which to delete the named group
.
group
-Scalar Stringgroup
to delete.
Deletes the specified user from the specified group.
server
- Scalar Stringserver
on which to delete user
from group
.
group
- Scalar Stringgroup
from which to delete user
.
user
- Scalar Stringuser
to delete from group
.
Enumerates all the global groups on the server. Unlike the API call
NetGroupEnum()
, this function does not allow you to specify a level
(internally it is hardcoded to 0). In Perl it is trivial to implement
the equivalent function (should you need it).
server
- Scalar Stringgroups
.
array
- Array Referencegroup
names.
Retrieves level
information for group
returning information in
hash
.
server
- Scalar Stringserver
from which to get the group information.
group
- Scalar Stringgroup
whose information you wish to obtain.
level
- Scalar Intlevel
of information you wish to retrieve. This can be one of 1, 2
or 3. See GROUP INFO LEVELS.
hash
- Hash Reference
Returns (in array
) the users belonging to group
. Unlike the API
call NetGroupGetUsers()
, this function does not allow you to specify
a level (internally it is hardcoded to 0). In Perl it is trivial to
implement the equivalent function (should you need it).
server
- Scalar Stringserver
from which to get the group information.
group
- Scalar Stringgroup
whose users you wish to obtain.
array
- Array Reference
Sets the information for group
according to level
.
server
- Scalar Stringserver
on which to set the group
information.
group
- Scalar Stringgroup
whose information you wish to set.
level
- Scalar Intlevel
of information you are supplying in hash
. Level can be
one of 0, 1 or 2. See GROUP INFO LEVELS.
hash
- Hash Referencelevel
.
error
- Scalar Stringerror
parameter will contain a value which specifies
which field caused the error. See GROUP FIELD ERRORS.
Sets the membership of group
to contain only those users specified
in array
. This function will fail if any user names contained in the
array are not valid users on server
. On successful completion
group
will contain only the users specified in array
. Use the
functions GroupAddUser()/GroupDelUser()
to add and delete individual
users from a group.
server
- Scalar Stringserver
on which to set the group
membership.
group
- Scalar Stringgroup
to set the membership of.
array
- Array Referencegroup
.
The LocalGroup*()
functions operate on local groups. If these
functions are run on a PDC then these functions operate on the domains
local groups.
Administrator or Account Operator group membership is required to successfully execute most of these functions on a remote server or on a computer that has local security enabled.
The server
field can be the empty string, in which case the function
defaults to running on the local computer. If you leave this field blank
then you should ensure that you are running the function on a PDC or BDC
for your current domain. Use the support function GetDCName()
to find
out what the domain controller is, should you not be running this on the PDC.
The following functions are available.
Adds the specified group. The name of the group is contained in the name
key of hash
.
server
- Scalar Stringserver
on which to add the group.
level
- Scalar Stringlevel
of information contained in hash
. This can be one of 0 or 1.
See LOCAL GROUP INFO LEVELS.
hash
- Hash Referencelevel
.
error
- Scalar Inthash
wasn't properly specified.
See LOCAL GROUP FIELD ERRORS for more information about what values
this can take.
LocalGroupAddMember()
This function is obsolete in the underlying API and has therefore not
been implemented. Use LocalGroupAddMembers
instead.
Adds the specified users (members) to the local group. Unlike the API
function NetLocalGroupAddMembers()
, this function does not allow you
to specify a level (internally it is hardcoded to 3).
This was done to simplify the implementation. To add a 'local' user, you
need only specify the name
. You can also specify users using the
DOMAIN\user
syntax.
server
- Scalar Stringserver
on which to add the members to group
.
group
- Scalar Stringgroup
to add the members to.
array
- Array Referencegroup
.
Delete the specified local group.
server
- Scalar Stringserver
on which to delete the named group
.
group
-Scalar Stringgroup
to delete.
LocalGroupDelMember()
This function is obsolete in the underlying API and has therefore not
been implemented. Use LocalGroupDelMembers()
instead.
Delete the specified users (members) of the local group. Unlike the API
function NetLocalGroupDelMembers()
, this function does not allow you
to specify a level (internally it is hardcoded to 3). This was done to
simplify the implementation. To delete a 'local' user, you need only
specify the name
. You can also specify users using the DOMAIN\user
syntax.
server
- Scalar Stringserver
on which to delete the members from group
.
group
- Scalar Stringgroup
to delete the members from.
array
- Array Referencegroup
.
Enumerates all the local groups on the server. Unlike the API call
NetLocalGroupEnum()
, this function does not allow you to specify a
level (internally it is hardcoded to 0). In Perl it is trivial to
implement the equivalent function (should you need it).
server
- Scalar Stringgroups
.
array
- Array Referencegroup
names.
Retrieves level
information for group
.
server
- Scalar Stringserver
from which to get the group information.
group
- Scalar Stringgroup
whose information you wish to obtain.
level
- Scalar Intlevel
of information you wish to retrieve. This can be 0 or 1.
See LOCAL GROUP INFO LEVELS.
hash
- Hash Reference
Retrieves the users belonging to group
. Unlike the API call
NetLocalGroupGetUsers()
, this function does not allow you to specify
a level (internally it is hardcoded to 0). In Perl it is trivial to
implement the equivalent function (should you need it).
server
- Scalar Stringserver
from which to retrieve the group information.
group
- Scalar Stringgroup
whose users you wish to obtain.
array
- Array Reference
Sets the information for group
according to level
.
server
- Scalar Stringserver
on which to set the group
information.
group
- Scalar Stringgroup
whose information you wish to set.
level
- Scalar Intlevel
of information you are supplying in hash
.
Level can be one of 0 or 1. See LOCAL GROUP INFO LEVELS.
hash
- Hash Referencelevel
.
error
- Scalar Stringerror
parameter will contain a value which specifies
which field caused the error. See LOCAL GROUP FIELD ERRORS.
LocalGroupSetMembers()
This function has not been implemented at present.
Gets the domain-controller
name for server
and domain
.
server
- Scalar Stringserver
whose domain controller you wish to locate.
domain
- Scalar Stringdomain
that server
is a member of whose domain-controller
you wish the locate.
domain-controller
- Scalar String (output)domain-controller
for the requested domain
.
Note: This module does not implement the NetGetAnyDCName()
API function
as this is obsolete.
Most of the User*()
functions take a level
parameter. This level
specifies how much detail the corresponding hash
should contain (or in
the case of a UserGet*()
function, will contain after the call). The
following level
descriptions provide information on what fields should
be present for a given level. See USER INFO FIELDS for a description of
the fields.
Note: This level is only supported on Windows Server 2003 and later.
Note: This level is only supported on Windows Server 2003 and later.
The following is an alphabetical listing of each possible field, together with the data type that the field is expected to contain.
acctExpires
- Scalar Int (UTC)authFlags
- Scalar Int (See USER_AUTH_FLAGS).UserAdd()
or UserSetInfo()
. Its value can be one
of:
User belongs to group Flag value --------------------- ---------- Print Operators Win32API::Net::AF_OP_PRINT() Server Operators Win32API::Net::AF_OP_SERVER() Account Operators Win32API::Net::AF_OP_ACCOUNTS()
badPwCount
- Scalar IntcodePage
- Scalar Intcomment
- Scalar StringcountryCode
- Scalar Intflags
- Scalar Int (Bitwise OR of USER_FLAGS)fullName
- Scalar StringhomeDir
- Scalar StringhomeDirDrive
- Scalar StringlastLogon
- Scalar Int (UTC)lastLogoff
- Scalar Int (UTC)logonHours
- Reference to Array of Integers (length 21 elements)logonServer
- Scalar StringmaxStorage
- Scalar Intname
- Scalar StringnumLogons
- Scalar Intparms
- Scalar Stringpassword
- Scalar StringUserGet()
operation.
password (array)
- 16 bytes arraypasswordAge
- Scalar Int (UTC)passwordExpired
- Scalar IntUserGetInfo()
the return value is 0 is the password has not expired
and 1 if it has. When setting the value via UserAdd()
or
UserSetInfo()
a value of 0 indicates that the users' password has
not expired whereas a value of 1 will force the user to change their
password at the next logon.
primaryGroupId
- Scalar IntUserAdd()
you should use a value of 0x201.
priv
- Scalar Int (Bitwise OR of USER_PRIVILEGE_FLAGS)UserGet()
call. See USER PRIVILEGE FLAGS.
profile
- Scalar StringscriptPath
- Scalar StringunitsPerWeek
- Scalar IntusrComment
- Scalar StringuserId
- Scalar IntUserAdd()
or
UserSetInfo()
calls.
userSid
- Scalar Stringworkstations
- Scalar String
The following is an alphabetical listing of the user flags.
The flags
key (see USER INFO FIELDS) should be the bitwise OR of one
or more of these values.
UF_ACCOUNTDISABLE()
UF_DONT_EXPIRE_PASSWD()
UF_HOMEDIR_REQUIRED()
UF_INTERDOMAIN_TRUST_ACCOUNT()
UF_LOCKOUT()
UserSetInfo()
call.
UF_NORMAL_ACCOUNT()
UF_PASSWD_CANT_CHANGE()
UF_PASSWD_NOTREQD()
UF_SCRIPT()
UF_SERVER_TRUST_ACCOUNT()
UF_TEMP_DUPLICATE_ACCOUNT()
UF_WORKSTATION_TRUST_ACCOUNT()
Please note that these are implemented as functions and are therefore called in the same way as other functions. You should typically use them like:
$ufScript = Win32API::Net::UF_SCRIPT();
These following values are used in the priv
key. This field is never
initialised on a UserGet*()
call and once set cannot be changed in a
UserSetInfo()
call.
USER_PRIV_ADMIN()
USER_PRIV_GUEST()
USER_PRIV_USER()
Please note that these are implemented as functions and are therefore called in the same way as other functions. You should typically use them like:
$userPrivUser = Win32API::Net::USER_PRIV_USER();
These flags are used in the UserEnum()
function to specify which
accounts to retrieve. It should be a bitwise OR of some (or all) of
the following.
FILTER_TEMP_DUPLICATE_ACCOUNT()
FILTER_NORMAL_ACCOUNT()
FILTER_INTERDOMAIN_TRUST_ACCOUNT()
FILTER_WORKSTATION_TRUST_ACCOUNT()
FILTER_SERVER_TRUST_ACCOUNT()
Please note that these are implemented as functions and are therefore called in the same way as other functions. You should typically use them like:
$filterNormalAccounts = Win32API::Net::FILTER_NORMAL_ACCOUNT();
For the User*()
functions that take an error
parameter this variable
will, on failure, contain one of the following constants. Note that the
function may fail because more than one key/value was missing from the
input hash. You will only find out about the first one that was incorrectly
specified. This is only really useful in debugging.
USER_ACCT_EXPIRES_PARMNUM()
acctExpires
field was absent or not correctly specified.
USER_AUTH_FLAGS_PARMNUM()
authFlags
field was absent or not correctly specified.
USER_BAD_PW_COUNT_PARMNUM()
badPasswordCount
field was absent or not correctly specified.
USER_CODE_PAGE_PARMNUM()
codePage
field was absent or not correctly specified.
USER_COMMENT_PARMNUM()
comment
field was absent or not correctly specified.
USER_COUNTRY_CODE_PARMNUM()
countryCode
field was absent or not correctly specified.
USER_FLAGS_PARMNUM()
flags
field was absent or not correctly specified.
USER_FULL_NAME_PARMNUM()
fullName
field was absent or not correctly specified.
USER_HOME_DIR_DRIVE_PARMNUM()
homeDirDrive
field was absent or not correctly specified.
USER_HOME_DIR_PARMNUM()
homeDir
field was absent or not correctly specified.
USER_LAST_LOGOFF_PARMNUM()
lastLogoff
field was absent or not correctly specified.
USER_LAST_LOGON_PARMNUM()
lastLogon
field was absent or not correctly specified.
USER_LOGON_HOURS_PARMNUM()
logonHours
field was absent or not correctly specified.
USER_LOGON_SERVER_PARMNUM()
logonServer
field was absent or not correctly specified.
USER_MAX_STORAGE_PARMNUM()
maxStorage
field was absent or not correctly specified.
USER_NAME_PARMNUM()
name
field was absent or not correctly specified.
USER_NUM_LOGONS_PARMNUM()
numLogons
field was absent or not correctly specified.
USER_PARMS_PARMNUM()
parms
field was absent or not correctly specified.
USER_PASSWORD_AGE_PARMNUM()
passwordAge
field was absent or not correctly specified.
USER_PASSWORD_PARMNUM()
password
field was absent or not correctly specified.
USER_PRIMARY_GROUP_PARMNUM()
primaryGroup
field was absent or not correctly specified.
USER_PRIV_PARMNUM()
priv
field was absent or not correctly specified.
USER_PROFILE_PARMNUM()
profile
field was absent or not correctly specified.
USER_SCRIPT_PATH_PARMNUM()
scriptPath
field was absent or not correctly specified.
USER_UNITS_PER_WEEK_PARMNUM()
unitPerWeek
field was absent or not correctly specified.
USER_USR_COMMENT_PARMNUM()
usrComment
field was absent or not correctly specified.
USER_WORKSTATIONS_PARMNUM()
workstations
field was absent or not correctly specified.
Some of the Group*()
functions take a level
parameter. This level
specifies how much detail the corresponding hash
should contain (or in
the case of a GroupGetInfo()
function, will contain after the call).
The following level
descriptions provide information on what fields
should be present for a given level. See GROUP INFO FIELDS
for a description of the fields.
Level 0
Level 1
Level 2
Level 3
Level 1002
Level 1005
attributes
- Scalar Intcomment
- Scalar Stringcomment
that applies to this group. This is the only value that
can be set via a GroupSetInfo call.
groupId
- Scalar IntgroupSid
name
- Scalar String
For the Group*()
functions that take an error
parameter
this variable will, on failure, contain one of the following constants.
Note that the function may fail because more than one key/value was
missing from the input hash. You will only find out about the first one
that was incorrectly specified. This is only really useful for debugging
purposes.
GROUP_ATTRIBUTES_PARMNUM()
attributes
field was absent or not correctly specified.
GROUP_COMMENT_PARMNUM()
comment
field was absent or not correctly specified.
GROUP_NAME_PARMNUM()
name
field was absent or not correctly specified.
The GroupGetUsers()
function can take a level of 0 or 1. These will
return the following:
Level 0
Level 1
name
- Scalar Stringattributes
- Scalar Int
Level 0
Level 1
Level 1002
name
- Scalar Stringcomment
- Scalar String
For the LocalGroup*()
functions that take an error
parameter this
variable will, on failure, contain one of the following constants. Note
that the function may fail because more than one key/value was missing
or incorrectly specified in the input hash. You will only find out about
the first one that was incorrectly specified. This is only really useful
for debugging purposes.
LOCALGROUP_NAME_PARMNUM()
name
field was absent or not correctly specified.
LOCALGROUP_COMMENT_PARMNUM()
comment
field was absent or not correctly specified.
The following example shows how you can create a function in Perl that
has the same functionality as the NetUserEnum()
API call. The Perl
version doesn't have the level parameter so you must first use the
UserEnum()
function to retrieve all the account names and then iterate
through the returned array issuing UserGetInfo()
calls.
sub userEnumAtLevel { my($server, $level, $filter) = @_; my(@array); Win32API::Net::UserEnum($server, \@array, $filter); for $user (@array) { Win32API::Net::UserGetInfo($server, $user, $level, \%hash); print "This could access all level $level settings for $user - eg fullName $hash{fullName}\n"; } } userEnumAtLevel("", 2, 0);
Bret Giddings, <bret@essex.ac.uk>
perl(1)
This work was built upon work done by HiP Communications along with modifications to HiPs code by <michael@ecel.uwa.edu.au> and <rothd@roth.net>. In addition, I would like to thank Jenny Emby at GEC Marconi, U.K. for proof reading this manual page and making many suggestions that have led to its current layout. Last but not least I would like to thank Larry Wall and all the other Perl contributors for making this truly wonderful language.
Win32API::Net - Perl interface to the Windows NT LanManager API account management functions. |