Tag Archives: ADSI

Get Local Group Members Revisited

The other day I posted an article and function that used ADSI and PowerShell to list members of a local group. I had a few people report an unusual error that I couldn’t replicate. During the course of troubleshooting, I made a few changes to the original function to at least better handle the mysterious error. Those changes were updated to GitHub and as version 1.5 of the function.

But during testing and revising, I decided I might as well really improve this command and incorporate an option to use PowerShell remoting, without having to jump through all the hoops in the previous version.

Version 2 of the function includes a few parameters for remoting. This meant defining a few parameter sets. I also turned the bulk of the ADSI code into a scriptblock which can by invoked normally using the & operator. Or run remotely with Invoke-Command. One tricky thing with scriptblocks is being able to flip on Verbose output.  My solution is to add a parameter to the scriptblock that essentially inherits the VerbosePreference of the local machine.

image

I also realized it might be helpful to include the group name in the results in case you want to export the information.

You can still use the command without remoting, which assumes you can create a legacy connection to the computer.

image

But I think you’ll find the remoting option better performing.

image

You can also use alternate credentials and SSL, although I haven’t tested using SSL or certificates since I don’t have that setup on my network.

Version 2 and later of the function can be found on Github:

Let me know if this works better for you.

Get Local Group Members with PowerShell

Recently I posted a function to get information about local user accounts. I received a lot of positive feedback so it seemed natural to take this the next step and create a similar function to enumerate or list members of a local group, such as Administrators.

The function, Get-LocalGroupMember, also relies on ADSI and is similar to my local user function so I won’t repeat the details.  Since I assume most of the time the only local group that matters is Administrators I made that the default.  I also set the computer default to the local host. But it is simple enough to query another computer.

image

You can pipe in computer names and use the object properties to do additional filtering, sorting or grouping.

image

In this example I wanted to search a group of computers and identify local members of Administrators that were not the Administrator account.

As with my previous function, I think you’ll find it better to use PowerShell remoting if you plan on querying multiple remote servers or need to use alternate credentials. You can read function help for more details.

You can always find the most current version of the function in my Github library.

I hope you find this useful. Comments are welcome here, but please post bugs or suggestions on GitHub.

Getting Local User Accounts the PowerShell Way

It seems I’m always seeing requests and problems on getting local user accounts using PowerShell.  However, even though we are at PowerShell 5.0,  Microsoft has never released a set of cmdlets for managing local user accounts. So many of us have resorted to creating our own tools. I now have my latest iteration of a function to get local user account information from remote computers.

The function takes a shortcut of sorts by using the ADSI type accelerator to connect to a remote computer. This is the same technique we used back in the VBScript days. However, this technique isn’t conducive to alternate credentials and requires legacy protocols like RPC and DCOM.  But that isn’t necessarily an issue as I’ll show you in a few minutes.

The function connects to the remote computer and then uses some COM object voodoo, to enumerate local account information. By default, the command will list all user accounts.

image

Or you can specify a single user account name.

image

The function accepts pipeline input making it easy to check multiple servers at once.

image

On important note: if you query a domain controller you will get domain accounts.

Remember I mentioned this command uses legacy protocols. One alternative is to use PowerShell remoting and Invoke-Command. First, create the necessary PSSessions, using alternate credentials if necessary.

Then get the function’s scriptblock.

Now you can use this with Invoke-Command:

image

Or query for a specify account:

image

You can find the complete script, which includes an alias on Github.

I hope you’ll let me know what you think and that you find this a useful addition to your PowerShell toolbox. If you run into problems, please post them on the Gist page.

Set Local User Account with PowerShell

halfuser The other day I received an email from a student asking for some help in using PowerShell to take care of a user account on a local computer. He not only wanted to be able to set the password, which he had already figured out, but also how to enable or disable the account, which is not obvious or intuitive without experience using ADSI and the WinNT provider. I sent him some suggestions to get him started down the right path. But I realized, I should wrap up this functionality in a PowerShell tool since his task is something I assume many of you need and there are no cmdlets from Microsoft for managing local user accounts.

First, let me point out that it is actually quite easy to manage local user accounts on remote computers using PowerShell. All you need to do is learn how to use the NET USER command and execute it using Invoke-Command.

remote-net-user-1

remote-net-user-2

The LocalAdmin account on CHI-CORE01 is currently disabled (account active is equal to no). But it is pretty easy to enable and set a new password.

However, this doesn’t scale well and the capabilities of the NET USER command might vary by operating system. So here is a PowerShell function that utilizes ADSI to do the same thing.

This function should work in PowerShell 2.0 and later. The help content includes some usage examples. You can use this command to simply change the user password, or change the password while enabling or disabling the account. Enabling and disabling is accomplished with a bitwise operation with the userflags value and a constant flag that indicates the account is disabled.

There is probably more that could be added to the command such as setting the comment property and when the account expires. But I’ll leave those changes to you for now.

Managing Local Admin with PowerShell

021913_2047_WordTest1.pngYears ago when I was deep into VBScript and HTAs, I wrote a tool called PWDMan. It was an HTA that processed a list of computers and returned password age information for the local administrator account. It was also capable of setting a new account password. Apparently this is still a common task because I’ll periodically get emails from people asking where they can get a hold of PWDMan. You can’t. And the reason is that we now have PowerShell and that is what you should be using, and if necessary, learning. So let me share a few examples of how to achieve the same functionality from my old PWDMan tool using PowerShell.

In the HTA, I used ADSI to connect to the remote computer and get the local administrator account. The object you get back has a PasswordAge property that is the number of seconds since the password was changed. So here’s a code sample.

In this example I’m defining a list of names. But you could easily read the contents of a text file with Get-Content or query Active Directory. Because you might have renamed the administrator account, or perhaps you need to check a different local acccount, I’ve created a variable for the account name. PowerShell then takes each computername and builds an ADSI connection to the administrator account, getting the passwordage value and dividing it by the number of seconds in a day. So $Age becomes the account password age in days. Because PowerShell is all about the objects, I create a custom object with some relevant information. Here’s the result.

local-admin-age

You may be wondering why I used ForEach-Object instead of the ForEach enumerator. That’s because the latter doesn’t write anything to the pipeline and I might want to save results to a text file or export to a CSV.

Be aware that I’m simply demonstrating some PowerShell examples. Ideally, you would want to build a tool to get the password information that you could combine with other PowerShell tools. In fact, what I’ve given you is close to being a function already but I’ll let you see if you can work it out. You want to be able to run a command like this:

The middle command is the tool you will build.

Now, what about changing the password? That too, can be accomplished with a one line command.

If you wanted to change the password for all of the machines that you reported on, it wouldn’t take much work to modify “get” code. So you see, using ADSI in PowerShell is just as easy, if not more so, than using it in VBScript.

There are a few caveats:

  • Don’t forget that the WinNT moniker is case sensitive.
  • There is no easy way to use alternate credentials.
  • There is no WhatIf support, unless you write a script that provides it.

My code samples here are intended as educational. You should take the time to build and test a more robust solution based on your needs. So the next time you think you need VBScript, stop and advance to PowerShell Place.