Hello,
I have a script that gets the local group memberships on some servers remotely. No problem running it in the context of an admin account. The problem is when I am trying to automate it and run it as a service account. Here is the part of the code that gives me trouble:

$password = 'someStringHere'
$serverName = 'computer001.domain.local'
$computer = [ADSI]"WinNT://$serverName"
$computer.psbase.Password = $password

And then when I type “$computer.psbase.Password” it shows as empty, without any value.
I have tried with:

$computer.psbase.Password = $credential.GetNetworkCredential().Password

still no difference.
This here doesn’t work too:

$computer = New-Object System.DirectoryServices.DirectoryEntry("DistinguishedName", "domain\username", "PasswordString")

In all cases the ‘$computer.psbase.username’ part populates successfully but the ‘$computer.psbase.Password’ part is always empty. Powershell doesn’t give any errors while executing the commands.
What am I doing wrong?

5 Spice ups

what is the password used for? If you are running as a service account locally you shouldn’t need to enter any credentials to get the local admin groups.

Or are you running this as a service account on a central machine which is then trying to use powershell remoting to query other machines and get their local group details?

3 Spice ups

Yes, I’m using it on a separate machine from which I query all the servers.
I’m using these lines to get the local group members:

$allGroups = $computer.Children | where { $_.SchemaClassName -eq 'group' }
            foreach ($group in $allGroups) {
                $groupName = $group.Name
                $members = @($group.psbase.invoke('members') | % { ([adsi]$_).Path })
1 Spice up

storing a credential in your script poses a security risk. You can store an encrypted credential, but the credential has to be encrypted by the same user \ process that is going to use it in order to be able to decrypt it.

for example to encrypt and store a credential

$cred = Get-Credential
$cred | Export-Clixml -Path "C:\Secure\serviceAccountCred.xml"

then to read it using the same process \ account

# Load credentials
$cred = Import-Clixml -Path "C:\Secure\serviceAccountCred.xml"

Export-Clixml (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn

you could also forgo the credential entirely if these servers are Active Directory Joined. To do this you could grant the Server Computer Object of the server running the script access to read properties on the member servers you want to query

for example.

Add-LocalGroupMember -Group "Distributed COM Users" -Member "DOMAIN\CentralServer$"

then you could run the script without credentials and it would authenticate automatically via Active Directory

# Define the path to the list of computers
$computerList = Get-Content -Path "C:\Path\To\computers.txt"

# Output file
$outputFile = "C:\Path\To\LocalGroupMembersReport.csv"
$results = @()

foreach ($computer in $computerList) {
    Write-Host "Connecting to $computer..." -ForegroundColor Cyan
    try {
        Invoke-Command -ComputerName $computer -ScriptBlock {
            $groups = Get-LocalGroup
            $groupData = @()

            foreach ($group in $groups) {
                $members = Get-LocalGroupMember -Group $group.Name -ErrorAction SilentlyContinue
                foreach ($member in $members) {
                    [PSCustomObject]@{
                        ComputerName = $env:COMPUTERNAME
                        GroupName    = $group.Name
                        MemberName   = $member.Name
                        MemberType   = $member.ObjectClass
                    }
                }
            }
        } -ErrorAction Stop | ForEach-Object { $results += $_ }
    } catch {
        Write-Warning "Failed to connect to $computer: $_"
    }
}

# Export results to CSV
$results | Export-Csv -Path $outputFile -NoTypeInformation
Write-Host "Report saved to $outputFile" -ForegroundColor Green

1 Spice up

The whole point of the topic is why this doesn’t work:

$computer = New-Object System.DirectoryServices.DirectoryEntry("DistinguishedName", "domain\username", "PasswordString")

According to the documentation and whatever old posts I have found on the internet, the “password” property should be able to take a string as a value. But in reality it doesn’t take any value and always stays empty.

1 Spice up

I don’t know why that doesn’t work, If I where to guess its because you are not using a secure string \ credential. what I suggested is an alternative that does work while being more secure.

1 Spice up

This method must accept a plain text. I’ve tried both a secure string and plain text and it accepts nothing.
I am using azure automation to run the script on a VM and I am using the credential store to get the credentials securely. No password is visible in the script.
WinRM is not enabled on most of the servers.

1 Spice up