• The company I'm working for has a GPO which maps drives for users who are members of certain groups to letters and paths. We're converting these GPOs to a new system which dynamically maps users using a logon script which looks for users in groups with a standard naming convention and in a certain OU and maps them to the path in the group description field. The migration process sometimes has errors, and I'd like to write a script to double check the process used by another group. I saw a posting by Tobias Weltner which looked like it would be a good start:

    $Xml.Machines.Machine | Where-Object { $_.Name -eq 'Server0009' } | Select-Object -Property IP, {$_.Information.info1}

    What I'm trying to do is look in every

    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive node and pull every
    
    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.properties.path
    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.properties.letter
    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.filters.filtergroup.name

    where the $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.filters.filtergroup.name -matches a group name entered in read-host or a gui menu.

    Everything I've tried results in ALL of the paths, letters, or group names being returned, not just the ones associated with the group name entered.

    Examples:

    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive | ? {$GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.filters.filtergroup.name -match "EU_Country_drivemap_GPO"} | select ($GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.properties).path

    and

    $GPO_report_drives = $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive
    foreach ($GPO_report_drive in $GPO_report_drives)
    {
    if ($GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.filters.filtergroup.name -match "EU_Country_drivemap_GPO")
    {
    $GPO_report.gpo.user.extensiondata.extension.drivemapsettings.drive.filters.filtergroup.name
    $GPO_report_drive.properties.path
    $GPO_report_drive.properties.letter
    }
    }

    Below is an example of one drive node:

    q1:Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="P:" status="P:" image="2" changed="2011-06-21 15:32:03" uid="{3BCD4228-1598-45BE-A994-DF073740B745}" userContext="1" bypassErrors="1">
    <q1:GPOSettingOrder>8</q1:GPOSettingOrder>
    <q1:Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="servernamePublic" label="Country PUBLIC" persistent="1" useLetter="1" letter="P" />
    <q1:Filters>
    <q1:FilterGroup bool="AND" not="0" name="DomainEU_Country_drivemap_GPO" sid="S-1-5-21-1417001333-790525478-839522115-749829" userContext="1" primaryGroup="0" localGroup="0" />
    </q1:Filters>
    </q1:Drive>

    I'm trying to produce output like: Groupname   Driveletter   Path

    for every drive letter and path for each group.

    I'll keep trying, but if someone has a solution or can point me in the right direction, I'd appreciate it.

    I know about select-xml, but have had less luck trying to use it.

    0
  • Your coding advice is excellent. It works fine, if I execute each line one by one in a powershell window. I had some time on my hands last Friday and wrote the script 3 ways, using net localgroup and get-ad* commands, net localgroup and dsquery/dsget, and ciminstance, with -split parsing and get-ad*.

    Today I figured out what I was looking for originally, which is how to isolate the win32_* account type from partcomponent. I was so close in the beginning, but didn't know that cimclass and cimclassname were what I was looking for.

    I drilled down like this:

    #$localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select -expand partcomponent

    $localgroup | get-member

    $localgroup | select *

    $localgroup | select name, domain, cimclass

    name domain CimClass
    ---- ------ --------
    Administrator ASUS-JIM ROOT/CIMV2:Win32_UserAccount
    Jim ASUS-JIM ROOT/CIMV2:Win32_UserAccount
    root ASUS-JIM ROOT/CIMV2:Win32_UserAccount

    foreach ($group_member in $localgroup) {$group_member.name}
    Administrator
    Jim
    root

    foreach ($group_member in $localgroup) {$group_member.domain}
    ASUS-JIM
    ASUS-JIM
    ASUS-JIM

    foreach ($group_member in $localgroup) {$group_member.cimclass}

    NameSpace: ROOT/CIMV2

    CimClassName CimClassMethods CimClassProperties
    ------------ --------------- ------------------
    Win32_UserAccount {Rename} {Caption, Description, InstallDate, Name...}
    Win32_UserAccount {Rename} {Caption, Description, InstallDate, Name...}
    Win32_UserAccount {Rename} {Caption, Description, InstallDate, Name...}

    foreach ($group_member in $localgroup) {$group_member.cimclass|select cimclassname}

    CimClassName
    Win32_UserAccount {Rename} {Caption, Description, InstallDate, Name...}
    ------------
    Win32_UserAccount
    Win32_UserAccount
    Win32_UserAccount

    foreach ($group_member in $localgroup) {$group_member.cimclass|select -expand cimclassname}
    Win32_UserAccount
    Win32_UserAccount
    Win32_UserAccount

    That's what I was looking for. I just had do some digging to find that cimclass was a peer property of name and domain in partcomponent.

    Now, for the rest of the story. Every get-ad* and ds* command line I executed individually in a powershell window worked fine. When I put them in a scripts, I get an access denied/unauthorized type message from AD or the DC. I'm at home now, so I don't remember exactly what it was. I'm stumped again.

    I sent an email to people in the security area who should know why I'm blocked from executing scripts against DCs and AD, and I can't wait to hear back.

    Thanks for all the help.

     

     

    0
  • Luke, my intention is to get the list of users and groups in the administrators and remote desktop users groups on a list of servers and if a user, get their samaccountname, givenname and surname from the domain they're in. If a group, drill down into AD in that domain, and find the users in the group, then get the samaccountname, givenname, and surname.

    I really appreciate the help you've provided.

    Thanks.

    0
  • There's more to the story. I'm hired as a backstop to the server admin team to handle specifically the server migrations, and just came in a couple weeks ago. The main work of migrating and merging domain users and groups, by the team who has been working on this for months, is done, as far as they're concerned, and they used micro$ft's and purchased tools. I'm supposed to shepherd the server domain migrations and any user/group/rights/application issues.  I see some gaps in tools and am trying to fill them in with powershell utilities, even if I have to wrap PSH around rmtshare and net commands.

    I found more tools/jump servers and at least one of them is at PSH 5.1. A couple others are at 4.0, and I'll try to get them upgraded. I gave up on cim/wmi, as my testing shows it's much too slow. I'm finishing my original script and working on others.

    As I understand it, unless every destination/remote server has PSH 5.1 installed on it, I can't use invoke-command or a pssession with get-localgroupmember in the scriptblock, anyway.

    0
  • How do I isolate the win32_* member type from get-ciminstance win32_groupuser | select partcomponent ?

    My goal is to get the group members from a windows server, using powershell; determine if they are AD domain users or groups, and if a group, drill down into the AD group to get the userids and full names.

    So far, I've tried get-ciminstance win32_groupuser, then feed that to Get-CimAssociatedInstance -Association win32_groupuser, but it's excruciatingly slow. I've tried net localgroup, and split the result into variables, and feed them to get-adobject to find out if they're users or groups using get-aduser and get-adgroupmember. That works, but it's a text based kludge, relying on an outside utility. I've also run the command "$localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent" and then split $localgroup to get $domain, $member_name, and $account_type, then fed them to get-aduser and get-adgroupmember commands. Another method I tried is $domain = $groupmember.partcomponent.domain and $username = $groupmember.partcomponent.name to get domain and membername, but I haven't been able to figure out how to get the member type from the partcomponent output.

    PartComponent
    -------------
    Win32_UserAccount (Name = "Administrator", Domain = "server1")
    Win32_Group (Name = "Domain Admins", Domain = "domain_1")
    Win32_UserAccount (Name = "_SVC_account", Domain = "domain_1")
    Win32_Group (Name = "domain_group1", Domain = "domain_1")
    Win32_Group (Name = "SEC_server1_LocalAdmins", Domain = "domain_1")
    Win32_Group (Name = "SrvAdmins", Domain = "domain_1")
    Win32_UserAccount (Name = "Admin-userid1", Domain = "domain_2")
    Win32_Group (Name = "ServerAdmins", Domain = "domain_2")
    ------------------------------------------------------------------------------------------------------------
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent
    foreach ($groupmember in $localgroup)
    {
    < #$domain = $groupmember.partcomponent.domain $username = $groupmember.partcomponent.name#>
    $account_type = ($groupmember -split " |=|""")[1]
    $account_type = $account_type.trim()
    $member_name = ($groupmember -split " |=|""")[6]
    $member_name = $member_name.trim()
    $domain = ($groupmember -split " |=|""")[12]
    $domain = $domain.trim()
    write-host "Domain: $domain Group Member: $member_name Account Type: $account_type"
    pause
    if ($domain -match "domain_1")
    {
    if ($account_type -match "group")
    {
    $userid = Get-ADGroupMember -server domain_1.com -identity "$member_name" | select samaccountname
    $username = Get-ADGroupMember -server domain_1.com -identity "$member_name" | select fullname
    }
    elseif ($account_type -match "user")
    {
    $userid = Get-ADuser -server domain_1.com -identity "$member_name"| select samaccountname
    $username = Get-ADuser -server domain_1.com -identity "$member_name" | select fullname
    }
    }
    }
    ------------------------------------------------------------------------------------------------------
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent

    $localgroup

    partcomponent
    -------------
    Win32_UserAccount (Name = "Administrator", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "Jim", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "root", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "sjm-user", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "abbott-user", Domain = "ASUS-JIM")
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent
    $localgroup | get-member

    TypeName: Selected.Microsoft.Management.Infrastructure.CimInstance

    Name MemberType Definition
    ---- ---------- ----------
    Equals Method bool Equals(System.Object obj)
    GetHashCode Method int GetHashCode()
    GetType Method type GetType()
    ToString Method string ToString()
    partcomponent NoteProperty ciminstance partcomponent=Win32_UserAccount (Name = "Administrator", Domain = "ASUS-PC")

    I can see that partcomponent is a noteproperty, but I'm not sure how to access it and isolate the "Win32_*" portion without -split as a string. Is there another way?

    I am aware of the get-localgroupmember cmdlet, but I'm working as a contractor in a large corporate merger, and powershell script execution is disabled on workstations. I have to use a jump server, which doesn't have 5.1 installed, and I have to work with what I have available.

    0
  • Jim Bendtsen posted a new activity comment 1 year, 3 months ago

    Sorry. First time, and I got it wrong. I'll start over. Thanks.

    0
  • Jim Bendtsen posted a new activity comment 1 year, 3 months ago

    Yes. I'm aware of that cmdlet, but I'm a contractor, working in a very large corporate AD migration, and gathering this information from potentially hundreds of servers, across the world. The OS versions vary from 2003-2016, and their powershell versions aren't all 5.1. I have to run this script on a jump server, which also doesn't have 5.1 installed, because I can't log on to my workstation with admin credentials, and powershell script execution is blocked on my workstation. My options are somewhat limited.

    0
  • Jim Bendtsen posted an update in the group Group logo of PowerShellPowerShell 1 year, 3 months ago

    How do I isolate the win32_* member type from get-ciminstance win32_groupuser | select partcomponent ?

    My goal is to get the group members from a windows server, using powershell; determine if they are AD domain users or groups, and if a group, drill down into the AD group to get the userids and full names.

    So far, I've tried get-ciminstance win32_groupuser, then feed that to Get-CimAssociatedInstance -Association win32_groupuser, but it's excruciatingly slow. I've tried net localgroup, and split the result into variables, and feed them to get-adobject to find out if they're users or groups using get-aduser and get-adgroupmember. That works, but it's a text based kludge, relying on an outside utility. I've also run the command "$localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent" and then split $localgroup to get $domain, $member_name, and $account_type, then fed them to get-aduser and get-adgroupmember commands. Another method I tried is $domain = $groupmember.partcomponent.domain and $username = $groupmember.partcomponent.name to get domain and membername, but I haven't been able to figure out how to get the member type from the partcomponent output.

    PartComponent
    -------------
    Win32_UserAccount (Name = "Administrator", Domain = "server1")
    Win32_Group (Name = "Domain Admins", Domain = "domain_1")
    Win32_UserAccount (Name = "_SVC_account", Domain = "domain_1")
    Win32_Group (Name = "domain_group1", Domain = "domain_1")
    Win32_Group (Name = "SEC_server1_LocalAdmins", Domain = "domain_1")
    Win32_Group (Name = "SrvAdmins", Domain = "domain_1")
    Win32_UserAccount (Name = "Admin-userid1", Domain = "domain_2")
    Win32_Group (Name = "ServerAdmins", Domain = "domain_2")
    ------------------------------------------------------------------------------------------------------------
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent
    foreach ($groupmember in $localgroup)
    {
    < #$domain = $groupmember.partcomponent.domain $username = $groupmember.partcomponent.name#>
    $account_type = ($groupmember -split " |=|""")[1]
    $account_type = $account_type.trim()
    $member_name = ($groupmember -split " |=|""")[6]
    $member_name = $member_name.trim()
    $domain = ($groupmember -split " |=|""")[12]
    $domain = $domain.trim()
    write-host "Domain: $domain Group Member: $member_name Account Type: $account_type"
    pause
    if ($domain -match "domain_1")
    {
    if ($account_type -match "group")
    {
    $userid = Get-ADGroupMember -server domain_1.com -identity "$member_name" | select samaccountname
    $username = Get-ADGroupMember -server domain_1.com -identity "$member_name" | select fullname
    }
    elseif ($account_type -match "user")
    {
    $userid = Get-ADuser -server domain_1.com -identity "$member_name"| select samaccountname
    $username = Get-ADuser -server domain_1.com -identity "$member_name" | select fullname
    }
    }
    }
    ------------------------------------------------------------------------------------------------------
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent

    $localgroup

    partcomponent
    -------------
    Win32_UserAccount (Name = "Administrator", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "Jim", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "root", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "sjm-user", Domain = "ASUS-JIM")
    Win32_UserAccount (Name = "abbott-user", Domain = "ASUS-JIM")
    $localgroup = Get-ciminstance -class win32_groupuser | where { (($_.groupcomponent).name -eq "Administrators") -and (($_.groupcomponent).domain -eq "$env:computername")} | select partcomponent
    $localgroup | get-member

    TypeName: Selected.Microsoft.Management.Infrastructure.CimInstance

    Name MemberType Definition
    ---- ---------- ----------
    Equals Method bool Equals(System.Object obj)
    GetHashCode Method int GetHashCode()
    GetType Method type GetType()
    ToString Method string ToString()
    partcomponent NoteProperty ciminstance partcomponent=Win32_UserAccount (Name = "Administrator", Domain = "ASUS-PC")

    I can see that partcomponent is a noteproperty, but I'm not sure how to access it and isolate the "Win32_*" portion without -split as a string. Is there another way?

    0
    • Did you give a try to the Get-LocalGroupMember cmdlet?
      You can find the source of a member in the name property.

      1+

      Users who have liked this activity:

      • avatar
      • Yes. I’m aware of that cmdlet, but I’m a contractor, working in a very large corporate AD migration, and gathering this information from potentially hundreds of servers, across the world. The OS versions vary from 2003-2016, and their powershell versions aren’t all 5.1. I have to run this script on a jump server, which also doesn’t have 5.1 installed, because I can’t log on to my workstation with admin credentials, and powershell script execution is blocked on my workstation. My options are somewhat limited.

        0
    • Jim, it is better to post questions in the PowersShell forum. These activity posts are only good for short messages such as links to news.

      1+

      Users who have liked this activity:

      • avatar
  • 0
  • Jim Bendtsen became a registered member 1 year, 3 months ago

    0