0

I am working on the easiest way to copy security settings from one server to another, using Powershell, and I'm curious if it's possible to import and entire group, including it's Description and Members properties?

Below is the script I currently have. It appears that I can access the local Group on the remote server using the ADSI adapter, however the Create command bombs with the following error message

Exception calling "Create" with "2" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))" At \prdhilfs02\install\Monet\ServerUpgrade\DEVHILWB119\Scripts\LocalUsersAndGroups.ps1:25 char:1+ $objCreate = $cn.Create("Group", $objRemote)

$computerName = "DEVWB89"
$objRemote = [ADSI]("WinNT://$computerName/$groupName")

$cn = [ADSI]"WinNT://localhost"
$cn.Create("Group", $objRemote)

EDIT

So I can accomplish what I want by using the script below. I can use the Group Name and Description from the remote server as well as the group information. However, is there a way to use Powershell to simply add the System.DirectoryServices.DirectoryEntry object, and all it's properties, to the local machine? Also, another drawback, is that I have to hard-code the domain for the Group's users.

$cn = [ADSI]"WinNT://localhost"
$computerName = "DEVWB89"

foreach($groupName in $groupArray)
{
    $objRemote = [ADSI]("WinNT://$computerName/$groupName")

    $objGroup = $cn.Create("Group", $($objRemote.Name))
    $objGroup.setinfo()

    $objGroup.description = $objGroup.Description
    $objGroup.setinfo()

    $Members = @($objRemote.psbase.Invoke("Members"))
    $Members | ForEach-Object {$MemberNames += $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) + ",";}

    $tempArray = $MemberNames -split ","

    foreach($member in $tempArray)
    {
        $objGroup.Add("WinNT://SYMETRA/$member, user")
    }
}
NealR
  • 10,189
  • 61
  • 159
  • 299
  • To start Create() probably wants a string and not an `System.DirectoryServices.DirectoryEntry` which is what `$objRemote ` – Matt Mar 02 '15 at 19:14
  • Yep, figured that. Do you know if it's possible to use a `System.DirectoryServices.DirectoryEntry` "object" to create a local group.. if that's possible and/or what the syntax would be? – NealR Mar 02 '15 at 19:49
  • `$cn.Create("Group", $objRemote.Name)` would probably make the group but that wont have the details you are looking for. `$objRemote.Description` has the description and I'm not sure off hand where the member list or if it is available. – Matt Mar 02 '15 at 19:51
  • Awesome, I'll keep looking. Thanks! – NealR Mar 02 '15 at 19:52
  • http://blogs.technet.com/b/heyscriptingguy/archive/2013/10/27/the-admin-s-first-steps-local-group-membership.aspx if it helps. If the machine is a domain member this could address some issues you might run into – Matt Mar 02 '15 at 20:02

1 Answers1

0

This will list out all the members of the groups:

$Members = @($objRemote.psbase.Invoke("Members"))
$Members | ForEach-Object {$MemberNames += $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null);}
$MemberNames

More helpful info:

PS C:\Users\YourUser\Desktop> $objAdmin = [ADSI]("WinNT://localhost/Administrator")
PS C:\Users\YourUser\Desktop> $objAdmin | gm


   TypeName: System.DirectoryServices.DirectoryEntry

Name                        MemberType Definition
----                        ---------- ----------
ConvertDNWithBinaryToString CodeMethod static string ConvertDNWithBinaryToString(psobject deInstance, psobject dnWithBinaryIns...
ConvertLargeIntegerToInt64  CodeMethod static long ConvertLargeIntegerToInt64(psobject deInstance, psobject largeIntegerInstance)
AutoUnlockInterval          Property   System.DirectoryServices.PropertyValueCollection AutoUnlockInterval {get;set;}
BadPasswordAttempts         Property   System.DirectoryServices.PropertyValueCollection BadPasswordAttempts {get;set;}
Description                 Property   System.DirectoryServices.PropertyValueCollection Description {get;set;}
FullName                    Property   System.DirectoryServices.PropertyValueCollection FullName {get;set;}
HomeDirDrive                Property   System.DirectoryServices.PropertyValueCollection HomeDirDrive {get;set;}
HomeDirectory               Property   System.DirectoryServices.PropertyValueCollection HomeDirectory {get;set;}
LastLogin                   Property   System.DirectoryServices.PropertyValueCollection LastLogin {get;set;}
LockoutObservationInterval  Property   System.DirectoryServices.PropertyValueCollection LockoutObservationInterval {get;set;}
LoginHours                  Property   System.DirectoryServices.PropertyValueCollection LoginHours {get;set;}
LoginScript                 Property   System.DirectoryServices.PropertyValueCollection LoginScript {get;set;}
MaxBadPasswordsAllowed      Property   System.DirectoryServices.PropertyValueCollection MaxBadPasswordsAllowed {get;set;}
MaxPasswordAge              Property   System.DirectoryServices.PropertyValueCollection MaxPasswordAge {get;set;}
MaxStorage                  Property   System.DirectoryServices.PropertyValueCollection MaxStorage {get;set;}
MinPasswordAge              Property   System.DirectoryServices.PropertyValueCollection MinPasswordAge {get;set;}
MinPasswordLength           Property   System.DirectoryServices.PropertyValueCollection MinPasswordLength {get;set;}
Name                        Property   System.DirectoryServices.PropertyValueCollection Name {get;set;}
objectSid                   Property   System.DirectoryServices.PropertyValueCollection objectSid {get;set;}
Parameters                  Property   System.DirectoryServices.PropertyValueCollection Parameters {get;set;}
PasswordAge                 Property   System.DirectoryServices.PropertyValueCollection PasswordAge {get;set;}
PasswordExpired             Property   System.DirectoryServices.PropertyValueCollection PasswordExpired {get;set;}
PasswordHistoryLength       Property   System.DirectoryServices.PropertyValueCollection PasswordHistoryLength {get;set;}
PrimaryGroupID              Property   System.DirectoryServices.PropertyValueCollection PrimaryGroupID {get;set;}
Profile                     Property   System.DirectoryServices.PropertyValueCollection Profile {get;set;}
UserFlags                   Property   System.DirectoryServices.PropertyValueCollection UserFlags {get;set;}


PS C:\Users\YourUser\Desktop> $Members[0].GetType().InvokeMember("FullName", "GetProperty", $null, $Members[0], $null)
Exception calling "InvokeMember" with "5" argument(s): "The specified domain either does not exist or could not be contacted.
"
At line:1 char:1
+ $Members[0].GetType().InvokeMember("FullName", "GetProperty", $null, $Members[0] ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : COMException

PS C:\Users\YourUser\Desktop> $Members[0].GetType().InvokeMember("PasswordAge", "GetProperty", $null, $Members[0], $null)
PS C:\Users\YourUser\Desktop> $Members[0].GetType().InvokeMember("UserFlags", "GetProperty", $null, $Members[0], $null)
Nathan Rice
  • 3,091
  • 1
  • 20
  • 30
  • This simply creates an array with a bunch of entries that read `System.__ComObject`. It looks like it's the array size is what it should be, however I can't seem to access any properties of the array items. For example, in a `foreach` loop this condition returns `false`: `if ($_.($member.name))` – NealR Mar 02 '15 at 22:18
  • That's right. I thought the intention was to copy the properties of the group. You need the properties of the members of the group too? – Nathan Rice Mar 02 '15 at 22:21
  • My bad, I misinterpreted what was going on in the loop. This does return a list of names, which I can use to add to the group. I would like to get the domain for each name as well, however. I've been looking for a list of properties for the System.__ComObject but I can find anything online for some reason. `Get-Member` doesn't seem to return anything if I loop through `$Members` either... any ideas? – NealR Mar 02 '15 at 22:25
  • You'll have to bind to each of the users individually to reveal their properties AFAIK. There is no way to enumerate their properties: http://stackoverflow.com/questions/18538840/is-it-possible-to-enumerate-all-methods-and-properties-that-are-available-via-in – Nathan Rice Mar 02 '15 at 22:43
  • I added some extra info that might be helpful for you. You can see if you bind to the user specifically you can enumerate all it's properties, but it doesn't look like all of them are exposed when you just list them via the group. Some return errors, other's just don't return any data. – Nathan Rice Mar 02 '15 at 23:00