This function should run on Windows Server 2003 and 2008 R2 Using the command line to execute it line by line is SUCCESSFULL! Execution by script fails.
function addUser2Group([string]$user,[string]$group)
{
$cname = gc env:computername
$objUser = [ADSI]("WinNT://$user")
$objGroup = [ADSI]("WinNT://$cname/$group,group")
$members = $objGroup.PSBase.Invoke('Members')
$found = $false
foreach($m in $members)
{
if($m.GetType().InvokeMember('Name', 'GetProperty', $null, $m, $null) -eq $user)
{
$found = $true
}
}
if(-not $found)
{
$objGroup.PSBase.Invoke('Add',$objUser.PSBase.Path)
}
$members = $objGroup.PSBase.Invoke('Members')
$found = $false
foreach($m in $members)
{
if($m.GetType().InvokeMember('Name', 'GetProperty', $null, $m, $null) -eq $user)
{
$found = $true
}
}
return $found
}
addUser2Group('MyGlobalMonitoringUser',"SomeDBGroup")
It should add a user to a local group. But it only gives me the following error:
Exception calling "Invoke" with "2" argument(s): "Unknown error (0x80005000)"
+ $members = @($objGroup.PSBase.Invoke <<<< ("Members"))
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Edit: the error message that occurs with /add is
The following exception occurred while retrieving member "Add": "Unknown error (0x80005000)"
Code is:
function addUser2Group([string]$user,[string]$group)
{
$cname = gc env:computername
try
{
([adsi]"WinNT://$cname/$group,group").Add("WinNT://$cname/$user,user")
}
catch
{
write2log($_)
return $false
}
return $true
}
Why go through the pain of reflection when PowerShell will do it for you? Example:
$group = [ADSI]"WinNT://./Power Users,group"
$group.Add("WinNT://SYSTEM,user")
The above adds the SYSTEM local account to the local Power Users group. I am not sure why you are getting the specific error above, you might get it with this abbreviated syntax as well. The particular COM interface that is being used is IADsGroup - reference here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa706021.aspx
Note: Because you are actually consuming COM objects wrapped in .NET objects, it is a good idea to call the Dispose
method on any ADSI objects that are created when you are finished with them.
Why wouldn't you use net localgroup /add
in your script instead of all that nasty looking WMI? PowerShell is a shell, not an operating system :)
Observations and assumptions
There are a couple of assumptions that are made based on the code.
Based on the fact that the incorrect parameter passing the value of the $group variable remains empty. It then caused the rest of the code to fail always returning the value of $False.
Proposed solution
Recommended Reading: Simplify your PowerShell Script with Parameter Validation
Include the Param "switch" in the function Change the way you call the function.
Here's a copy of the code that works.
function addUser2Group
{
# Added the Param Switch
Param(
[string]$user,
[string]$group
)
$cname = gc env:computername
$objUser = [ADSI]("WinNT://$user")
$objGroup = [ADSI]("WinNT://$cname/$group,group")
#$members = $objGroup.Invoke('Members')
$found = $false
foreach($m in $members)
{
if($m.GetType().InvokeMember('Name', 'GetProperty', $null, $m, $null) -eq $user)
{
$found = $true
}
}
if(-not $found)
{
$objGroup.PSBase.Invoke('Add',$objUser.PSBase.Path)
}
$members = $objGroup.PSBase.Invoke('Members')
$found = $false
foreach($m in $members)
{
if($m.GetType().InvokeMember('Name', 'GetProperty', $null, $m, $null) -eq $user)
{
$found = $true
}
}
return $found
}
addUser2Group -user 'testing' -group "Administrators"
•0x80005000 ("The specified directory service attribute or value does not exist").
Parameter binding or Environmental culprit perhaps?
As for the issue with net localgroup: examine the error message carefully:
The following exception occurred while retrieving member "Add"
Evidentally the /add
flag is not being properly set as it is being interpreted as a member name, but since no code is provided, can't say why.
Just to add a more uptodate approach roughly five years later:
$group = Get-LocalGroup SomeDBGroup
$user = Get-LocalUser MyGlobalMonitoringUser
Add-LocalGroupMember $group $user
User contributions licensed under CC BY-SA 3.0