Posts Tagged ‘Powershell’

Powershell – How recursive directory searches got better with PSv3…

April 18th, 2013 by Jeremy Pavlov | No Comments | Filed in Microsoft, PowerShell, Scripting

In the old days, we ate dirt for dinner, brushed our teeth with sticks, used PowerShell v2 — and we *liked* it! 

There, that’s my tribute to Dana Carvey as “Grumpy Old Man”.  Google it, kids.

Anyway, I’ve got an absolute ton of old PowerShell scriptlets that I have lying about that I regularly cannibalize or resuscitate back into production.  And since we are in that squishy transitional period between PowerShell v2 and v3, I don’t always bother to check them for compatibility with v3 or update features in the script to take advantage of new capabilities.  But I hit on one v3 improvement the other day that solved a problem has bugged me so much for so long that I wanted to shout from the mountaintops about it!  And since I live in mostly-mountainless Michigan, the blog is the best I can do…

Really it’s such a little thing.  But it’s so overdue.

In the past, if you wanted to recursively inspect a folder structure on a remote server — for instance while fishing for explicit NTFS permissions on folders — you were forced to inspect all folders *and* files, no matter if you only wanted folders.  Basically, you had to ask for everything (all children folders and files, recursively), then parse the result to extract the folders (check psIsContainer) from the listing.  Here’s an example of this, similar to what you might see all around the internet:

# For PowerShell v2
$containers = Get-ChildItem -path $TopPath\$CurrentParent -recurse | ? {$_.psIscontainer -eq $true}

 Of course, this could be incredibly wasteful in processing, network bandwidth, time, etc…   All this time I’ve always wished there was a way in my loops to just ask for ONLY the folders, to save all of that waste.  Thankfully, this has arrived with v3.  Behold:

# For PowerShell v3
$containers = Get-ChildItem -Directory -path $TopPath\$CurrentParent -recurse

 This has significantly sped up some of my analysis scripts that I run in a large enterprise, cutting as much as half a day off of some of my execution times (I did mention it was large).  So really what this means is that I have to start spending more spare time looking through the v2/v3 differences…  But I won’t have any spare time until I implement more v3 changes…  Quite a conundrum… 

;)

 

Did you like this? Share it:

Tags: , , , , ,

Powershell – Query Active Directory for Server Versions…

March 21st, 2013 by Jeremy Pavlov | No Comments | Filed in Microsoft, PowerShell, Scripting

Today, I’m writing about a simple-but-useful command that just might help you get a better understanding of the quantity and variety of Windows servers you have in your environment, with just a few caveats.  The most accurate way to get such information, of course, is to query Active Directory in real-time to get the most current information possible.  And the easiest way to do that (in my opinion), is to use PowerShell.  So launch a console and let’s get to it…

But first, if you haven’t launched the pre-loaded Active-Directory PowerShell Module, then let’s do that now:

Import-Module ActiveDirectory

Here’s a first blush at how we can list all AD-based computers, grabbing only the interesting properties we need, formatting the output to a list, and redirecting the results to file (I’ve seen some things like this while ‘Googling):

Get-AdComputer -Filter * -Properties IPv4Address,OperatingSystem,OperatingSystemServicePack | Format-List Name, IPv4Address, OperatingSystem* > OutputServerList.txt

Now, let’s dig deeper, and perhaps refine the command a bit.  First, the filter is a wildcard, and retrieves all computers.  That might be fine in a small environment with few computers; but we’re really only after Servers here, and we might be working in a larger environment.  So, we will change the filter to use an LDAPFilter and get a bit more granular like this:

-LDAPFilter "(OperatingSystem=*Server*)"

Next, I think the results will actually look better if we output them to a CSV, so we’ll drop the redirect and list formatting, and replace it with a pipe like this:

| Export-Csv ExportCsvServerList.csv

Now a warning about the CSV export…  Unfortunately, Microsoft chose to include a “restricted” symbol (little r in a circle) in the Server 2008 (non-R2) name, like this:

Windows Server® 2008 Standard

…and, the CSV export operates only with the ASCII set by default.  Sheesh.  So, we use the UTF8 flag to make sure the wacky “restricted” mark is rendered correctly, like this:

| Export-Csv -Encoding UTF8 ExportCsvServerList.csv

So with all that, we end up with a command looking like this:

Get-AdComputer -LDAPFilter "(OperatingSystem=*Server*)" -Properties IPv4Address,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion | Export-Csv -Encoding UTF8 ExportCsvServerList.csv

And since it’s a spreadsheet you can further filter/format/manipulate the results how you see fit.

One more thing that causes confusion sometimes: 

Be aware that even though we are calling ActiveDirectory for these servers and their correlating properties, there’s one of these items that don’t come from there: the IP Address.  As you are likely aware, the IP address of a computer object is not stored in the directory; so what is actually happening is that the Get-AdComputer module is retrieving the FQDN of the computer, and doing a DNS query to resolve it to the address for you. 

Now, this can be good or bad, depending on your situation; for instance, it might slow down your 8000+ server export… or might also help alleviate the burden on your AD server as you make the query (while it delays the processing a tad to retrieve the name).  Also, you’d better be able to rely on your DNS to return valid values, or the results might be confusing/misleading! 

I hope that helps…  Thanks for reading, and by all means if you have additional tips, be sure to comment!

 

 

 

Did you like this? Share it:

Tags: , , , , , , , , , ,

PowerShell – Detect Group Membership Type…

March 7th, 2013 by Jeremy Pavlov | No Comments | Filed in Microsoft Infrastructure, PowerShell, Scripting

It should come as no surprise that adherence to naming conventions and good Active Directory (AD) Organizational Unit (OU) structure are things that can make an Enterprise Administrator’s life much easier. 

Take, for example, the situation of having a naming convention for group objects in AD that dictates a single-letter suffix of either a “C” (to indicate a group of computer objects) or a “U” (for a group of user objects).  In this case, a group might be named something like, “Detroit Application Data U”, or “Chicago Printers Floor2 C”.  And with intentions such as these — and human beings being what they are — it’s inevitable that some users will end up in computer groups, and vice versa.

So how to we check for this messiness?  With PowerShell, of course…

We create a script that will accept an array of our AD OUs (or group-specific OUs if you’re lucky), loop through them, grab all the groups and the memberships, and do a validation to make sure the members are of the correct class (note that I could fill up pages of the lines of code for this, depending on your specifics; so I’ll just stick with the main conceptual points).  Let’s dive into the code snippets!

First, add your OUs into an array, and other variables.  Of course, you might not be able to just scrape a level with PowerShell and grab all your OUs…  Oh, but you *do* have a perfectly-regulated AD hierarchy, don’t you?  Whether it’s perfect or not, AD structure goes a long way here; and my examples show how convenient it is if you have all your groups in a standard ou=GROUPS structure or some predictable way.

$OUs = @("Detroit", "Chicago", "Los Angeles")
$MyDomain = "dc=MyDomain,dc=org"

Then you start to loop and grab all the groups in an OU:

foreach ($OU in $OUs)
{
  #... skipped a few more lines of code here...
# Here we get the list of our groups for the loop
$OuGroupNames = Get-ADObject -Filter {(ObjectClass -eq "group") -and ((name -like "* U") -or (name -like "* C"))} -SearchBase "ou=Groups,ou=$OU,$MyDomain"

And, now that you have the groups, you can start to evaluate each group like this:

  foreach ($OuGroup in $OuGroupNames)
  {
    #...skip more code.. What are we skipping here? Oh, validations, error-checking, and stuff...
# we need the group name and DN    $OuGroupName = $OuGroup.Name     $OuGroupDn = $OuGroup.DistinguishedName

Now, we can truly check the object membership type!

    # If it is a user group...
if ($OuGroupName -like "* U")     {       $MemberList = Get-ADGroupMember -Identity "$OuGroupName"
# ...it had better be a user...       if ($Member.ObjectClass -like "computer")
{
#...or we kick out an error to the report!

And so on.  Of course, you’d do the converse of the snippet above for a user-type object in a “C” group.  By the way, this can lead to all kinds of other error detection too; in fact, the main reason I couldn’t show all my code is that I ended up adding checks for empty groups, groups with members from external OUs, and so on.  Because basically, once you have the group attributes and its membership list in hand, you may as well do some validation while you’re there…

So have fun with it, and see where it leads you…  And make sure to drop me a line if you need any help putting the whole thing together.

:)

 

 

 

 

Did you like this? Share it:

Tags: , , , , ,

How To Query Active Directory For Object Group Memberships…

February 7th, 2013 by Jeremy Pavlov | No Comments | Filed in PowerShell, Scripting

Not too long ago, I was working with a colleague who was doing a lot of user management and provisioning, and needed to be able to look up the group membership of a user (or a computer) without being too complex or having to memorize anything.  So I installed RSAT on the computer, and made a little batch file that he could run that will take the username (as samAccountName) and dump out the direct or inherited memberships.  Easy as pie.

And as I often do, I thought I’d put up a little blog post detailing the mechanics and concepts of the script.  Of course, we’ve touched on some of these concepts before in this blog, but never in this direct of a way.  So without further ado…

How to Check Group Memberships from the User or Computer Perspective

If you already have the userID/samAccountName, then you can check *user* DIRECT group memberships like this example:

dsquery user -samid "JPavlov" |dsget user -memberof

…and to check *user* INHERITED group memberships, use the expand flag:

dsquery user -samid "JPavlov" |dsget user -memberof -expand

 

Similarly, you can check *computer* DIRECT group memberships like this example:

dsquery computer -name "CTS004895" |dsget computer -memberof

…and to check *computer* INHERITED group memberships:

dsquery computer -name "CTS004895" |dsget computer -memberof -expand

 

How to Check Groups Memberships from the Group Perspective

Of course, I just can’t leave it there.  What if you want to approach it from the other direction?  For instance, if you have a group name (or a prefix if you have a naming convention), and you want to get a membership list of that group?  It’s still doable.  And while I’m at it, I thought I’d sprinkle in a little bit of PowerShell, and still use dsquery to get the job done, as in the following example:

$StartingContext = "OU=Groups,OU=Location,DC=Coretek,DC=local"
$GroupPrefix = "CTS FH "
$GroupList = dsquery * $StartingContext -limit 9000 -filter "(&(objectClass=Group)(name=$GroupPrefix*))" -attr samAccountName,member
$GroupList

…and this works, but… unfortunately, the output is horrible because the dsquery output is ugly.  But, if you happen to already have a list of group names (as in my example groupList.txt below), you could do something like in this example:

$GroupList = Get-Content .\groupList.txt
$StartingContext = "OU=Groups,OU=Location,DC=Coretek,DC=local"
foreach ($GroupItem in $GroupList)
{
  write ""
  write "Group is $GroupItem"
  dsquery * $StartingContext -limit 9000 -filter "(&(objectClass=Group)(samAccountName=$GroupItem))" | dsget group -members
}

…and while it’s basically the same dsquery as in the snippet above, the output is much nicer — since we are piping it into dsget, which makes for a much prettier report. 

Now… perhaps my favorite of all, we can do pretty much the same procedure as the previous command, but this time all in PowerShell, and using the Get-AdGroup command (remember to import the ActiveDirectory module!):

$GroupPrefix = "CTS FH "
$MemberList = Get-ADGroup -ldapFilter "(&(objectClass=Group)(name=$GroupPrefix*))" -Properties Members
foreach ($MemberItem in $MemberList)
{
  write ""
  write "Membership for: $MemberItem"
  $MemberItem.Members
}

And that’s it!  You should have a list of group members for the correlating groups. 

So as usual, we have a couple ways to do a few different things.  Have fun with it!

 

 

Did you like this? Share it:

Tags: , , ,

PowerShell v3 and DNS Queries…

January 31st, 2013 by Jeremy Pavlov | No Comments | Filed in PowerShell, Scripting

As I mentioned in last week’s post, “PowerShell v2 and DNS Queries…“, it is much easier to do scripted DNS queries in PowerShell v3 than it is in v2 — thanks to the new Resolve-DnsName command.  Following along the same lines as the previous post, and using the exact same example hosts, we can show the same correlations and results for comparison. 

We’ll start off with a request similar to our first nslookup in the previous post, but this time using the Resolve-DnsName command:

And as before, the same holds true with out multi-valued results:

On its face, the results are very similar to nslookup results.  However, since we’re dealing with objects here instead of scraped screen executable output, we can actually manage our results very neatly.  Here’s what I mean, as I enclose the object, and only request the “.IpAddress” from it for my two example hosts:

See how neat, clean, and powerful that is?  This same thing works with other object elements, like “.NameHost“, and such.  By the way, I’ve seen some advice posts out on the ‘Net that advise you to use an increment indicator like this:

(Resolve-DnsName $server_name)[0].IpAddress

…but that will cause you to only get the first result returned!  And sometimes, that may be what you’re after; but in the case of the multivalued host, that’s probably not what you want.

Now, to contrast last week’s post, I’ll show you how we take the 12-line PowerShell v2 script down to a 3-line PowerShell v3 script:

$ARecord = "labdc1.lab.local"
$NameServerQueried = "192.168.6.4"
(Resolve-DnsName -Name $ARecord -Type A -Server $NameServerQueried -ErrorAction SilentlyContinue).IpAddress

 …But of course, it’s only 3 lines because 2 of them are variables; but it’s a fully functional equivalent.  And you can start to see how efficient it can be when looped.  And for the sake of completion of the comparison, here’s the results of my v3 script with the “fakehost” multi-valued host:

…and with the original “labdc1″:

So there you have it.  We love the new commands in PowerShell v3, and they are making our lives soooo much easier (once you know about them).   Now, I’m just waiting for the commands I’ve been asking for… Like Get-MyCoffee… and Get-WorldPeace…. and Solve-GlobalHunger

;)

 

 

 

Did you like this? Share it:

Tags: , , , , ,

PowerShell v2 and DNS Queries…

January 24th, 2013 by Jeremy Pavlov | 1 Comment | Filed in PowerShell, Scripting

For this week’s (and next week’s) post, I decided I’d kill a few birds with one stone.  Since it’s “PowerShell month” here at TekTopics.com, and since I’m still making my way through all the differences between PowerShell v2 and v3 (like we all are), I thought I’d tell you about how I just discovered how a relatively simple thing was relatively hard to do in PowerShell v2, and how it got relatively WAY easier in PowerShell v3:  DNS lookups.

Probably like you, I’ve been doing DNS queries for years in all kinds of scripts and languages — like bash, perl, DOS batch files, and of course, PowerShell.  And up until recently, I treated them all pretty much the same — in that I typically just made a system call out to running OS and used the native DNS client query tool, nslookup.  Of course this requires that I grab the output of the tool, scrape out just the information I want (and ignore other data), and continue on to make use of it.

However, in PowerShell v2, the problem is that when trying to grab the desired results back from the system call, the resulting address from the query is not as easy to discern from the “courtesy” information that is returned along with the answer from nslookup.  What I mean is that searching for the string “Address” could get you in trouble, since you end up with two lines that start with “Address” — the one you don’t want (the address of the server that was queried), and the one you want (the query response). 

And in some cases, they could theoretically be the same value, especially if you’re looping through a list of nameservers and query the name of the server you’re querying.  See what I mean in this unfiltered example query and response: 

 

Note that the record could be multi-valued too, like this example:

So if I just attempt to grab all the strings that match “Address”, as in the following…:

…I could end up with some strange results.  So, instead, I search for all strings in the form of an IP address, and I implement a simple counter to skip the first one, catch any subsequent ones, and split the result to strip out the words.  Here’s the code for my loop:

$ARecord = "fakehost.lab.local"
$NameServerQueried = "192.168.6.4"
$FullAddressList = nslookup -type=a $ARecord $NameServerQueried | findstr "[0-9].[0-9].[0-9].[0-9]" 
$counter = 0
foreach ($line in $FullAddressList)
{
  $counter = $counter + 1
  if ($counter -ne 1)
  {
    write "$line" | %{ $_.Split(" ")[2] }
  }
}

…and here are the results, with the query for the multi-valued “fakehost” host record, as in the $ARecord variable as above (inside my Example.ps1 script):

…and with the original “labdc1″ nameserver query, as in my first example:

As you can see, DNS queries are do-able in PowerShell v2, but it’s a pain.  The little snippet above should work just fine inside of a larger loop in a validation script, or on its own, for whatever you need to get done.  And I’m sure there are other ways to accomplish the same thing, but this has worked for me in the past (and present) in PowerShell v2. 

Well — now, there’s a new way of getting the same queries done in PowerShell v3, that is much, much, much easier…  And I will jump into that next week.  See you then!

Next week:   The PowerShell v3 way!

 

Did you like this? Share it:

Tags: , , , , ,

PowerShell Basic Commands 101

January 17th, 2013 by Matthew Sharland | No Comments | Filed in PowerShell, Scripting

It looks like January has turned into “Powershell Month” here at the TekTopics.com! 

And while typically, we write these Powershell-related posts with the assumption that you’re already at least reasonably versed in the language, I thought it might be good to give a few introductory tips to those of you who need the first few basics of Powershell to get you up and running.  Then, you can take these tips and start getting creative with some of the great scripts, loops and commands we’ve talked about here in this blog.

First off, when in the PowerShell command prompt type in “Get-Command” and hit enter:

Get-Command

This will list every PowerShell command available. It is quite lengthy, but can be very helpful if you have the time to scroll through the entire list to discover new and exciting scripting tools.

If you wanted to save this list, you could by outputting it to a file by using the “|” (“pipe”) combined with the “Out-File” command, for example:

Get-Command | Out-File C:\Commands.txt

If you are like me and require the list to be sorted by “practical application” then you can sort it by `Module Name’ by simply running:

Get-Command | Sort Module

You can then take it one step further to narrow your search results by filtering by Module name and a “*” (wildcard) as seen here an example of searching for BitLocker:

Get-Command -Module BitLock*

Or if you are looking for a specific command to run to `Enable’ BitLocker:

Get-Command –Module BitLock* -Name Enable* 

From there, if you need usage commands or examples of any newly found Powershell command you can use the “Get-Help” command. The following example would give you helpful information for the “Get-Command” cmdlet as previously mentioned:

Get-Help Get-Command

Or for “Select-String”, the PowerShell equivalent to “FindStr” or the ever-so-popular string search tool called “Grep”:

Get-Help Select-String

One final note to tie this all together: Instead of memorizing the entire cmdlet, module or function names you can use the built-in aliases, which are shorter commands that execute the same command as the long name function, for example: gcm is Get-Command and help is Get-Help

So you could run the following command, which is the same as the above “Get-Help Get-Command”:

help gcm

And you can view the entire list of “Aliases” by running:

gcm -Type Alias

That is all for now! Stay tuned for PowerShell Basic Scripting 101!

 

 

Did you like this? Share it:

Tags: , , , , , , , , , ,

Powershell: Script to Easily Find Objects in the SCCM Console

January 10th, 2013 by Paul Opper | No Comments | Filed in PowerShell, SCCM, Scripting

Recently, I had a need to delete an SCCM advertisement in the SCCM 2007 R2 console, in order to ensure it didn’t run on any of my test machines.  Now, I knew that it wouldn’t run, because it was not being advertised to any collections of which my test machine was a member.  But the advertisement was only a test, and I was trying to clean up after myself.

According to Microsoft (link: http://technet.microsoft.com/en-us/library/bb693527.aspx), the way to delete an advertisement from the SCCM console is to drill down through the console (System Center Configuration Manager / Site Database / Computer Management / Software Distribution / Advertisements) and right-click -> Delete the advertisement.  Normally, this is a pretty straightforward procedure…  IF you know where your advertisement is located.

You see, the SCCM console in which I was working divided the advertisements into sub folders based on the Publishers name, and I could not find a folder for the Advertisement I was trying to delete.

 Consol.Advertisements

 

Furthermore, subdividing the Advertisements as such also rendered the “Look For” search field in the console pretty useless; I would have to “Look For” my advertisement in every folder!

SCCM reports can be pretty helpful, and I was able to run a report that gave me just about every piece of data about the advertisement I wanted to delete – except the path to it; the information critical for deleting the advertisement.

A quick Google search led me to this link: http://blog.tyang.org/2011/05/20/powershell-script-to-locate-sccm-objects-in-sccm-console/.  Here, I found the Powershell script that helped me find my elusive advertisement.

The only inputs for this powerful and very useful script are the name of your SCCM site server, and the SCCM object ID, which can easily be found through the “All Advertisements” report in SCCM.  As it turns out, the folder that contained my advertisement had been accidentally moved under another folder. 

It’s great when you find the perfect tool for the job, as I did in this case.  I hope you find it as useful as I did. I intend to keep this one around for future use. 

Thanks, Tao!

 

Did you like this? Share it:

Tags: , ,

Powershell: Get-ADUser Without Errors…

January 3rd, 2013 by Jeremy Pavlov | No Comments | Filed in Microsoft, PowerShell, Scripting

I do a lot of scripting of mass-user searches, server and Home Folder validations, etc., where I rely on the Powershell command “Get-ADUser” in my loops.  And this is one of those cases where Powershell is very forgiving; and as such, things like this can be done a handful of different ways.  Of course, some are better than others…

The shortest and easiest form of the command is often fine enough to get the job done, but not always the best in certain situations.  For instance, if you have an IF loop where you are going through an expected list of users (perhaps from an input file) and trying to retrieve a certain attribute for each, you might be inclined to initially write the loop line something like this:

Get-ADUser -Identity $loopUserId

…and this is fairly standard, of course.  In the resulting loop, it would return something like the standard set of attributes in this capture (using a manual query in my lab for this example)

 However, if you are like me, you might occasionally want to watch the output of your scripts while they run; and you prefer to send nice results to screen (as well as to the output logs) for easy debugging and, well, entertainment. 

And this is where the problem arises with the simple format of the command; you soon become annoyed by all the red error messages for the users that have gone missing since your input file was created, as in the case of this intentional search for a non-existent user:

…this is because by default, the Get-ADUser command will give you a nice set of results when it succeeds, but an ugly red message when there is no result.  Yuck.  This simply won’t do; we don’t want to have to panic as if there were an actual *error* every time we get an empty result on each query in the loop!

Instead, we wish to just get a silent, non-return when there are no results.  So, another way to write the same command so that you don’t get any error messages is by using the -Filter option, like this:

Get-ADUser -Filter {SamAccountName -eq $loopUserId}

In this manual example, you can see that the results are the same as if using the earlier format of the command when successful:

…But this time, we get a nice, quiet, non-result in the event of an empty response; as in the case of the same failed search:

Much better!

Now, you can watch your loop output while having a nice… calm… lunch….

 

 

Did you like this? Share it:

Tags: , , , ,

Scripted Home Folder Management with PowerShell Pt. 6 – The Script!

October 4th, 2012 by Jeremy Pavlov | No Comments | Filed in Microsoft, PowerShell, Scripting, Windows 7

This is the last post in my series on scripting user and Home Folder management (see Part 1, Part 2, Part 3, and Part 4 and Part 5 for reference) — it was a lot of ground to cover, but we did it!  Thanks for hanging in there with me.  We’ve created the user and attributes, built the folder, set permissions, added the Home Folder attribute on the user object; all with PowerShell.  You don’t get much more real-world than that!

Now, as promised, it’s time to pull it all together into one example script.

Of course, now that we’re putting all the concepts from the previous posts together, we need to be smart and add a few smart/standard script things; like good use of variables, error checking, and so forth.  Specifically, the new things I’m introducing in this post are:

  • Use of variables  – To make the script portable and easily modifiable
  • Use of command line arguments – To accept the new user’s name as input arguments
  • Use of SubString – To generate a “UserName” (a.k.a. SamAccountName) from a first and last name
  • Check for pre-existing – To make sure we don’t attempt to create an already-existing user name

All of the items above are in the first section of the script below, and the remaining sections are where I pull in the concepts from the previous posts to get it all done.  I don’t want to go into great detail on these new items, but they are necessary to make the script flow correctly and be usable right away as-is.

So, here you go.  You can paste this right into a file (something like provisionNewUser.ps1), launch a PowerShell session, and run it with the new user’s First Name and Last Name on the command line (as explained early in the body of the script). 

And here’s my warning: Don’t ever do what people on the Internet tell you to do; if this script is scary to you, don’t run it.  In fact, only run this in a test lab, until you are comfortable with the specifics.  So there.

# Home Folder Provisioning Demo Script
# Jeremy Pavlov, Coretek Services, 20121003
#
# Execute in a powershell session, with the new user's First and Last names after the command, like this:
# .\provisionNewUser.ps1 Jeremy Pavlov
# # Make sure you run this if not already loaded, for AD-based commands Import-Module ActiveDirectory # # Read in the first name and last name from command line inputs $FirstName = $args[0] $FirstInitial = $FirstName.Substring(0,1) $LastName = $args[1] $LastInitial = $LastName.Substring(0,1) $UserName = "$FirstInitial$LastName" $MyDomain = "CoretekServices.local" $HomePrefix = "\\$MyDomain\Corp\Homes" $DefaultUserOu = "ou=New Users,dc=CoretekServices,dc=local" # write "First name will be: $FirstName" write "Last name will be: $LastName" write "User name will be: $UserName" write "Home Folder will be: $HomePrefix\$LastInitial\$UserName" write "" # # See if the user exists $CheckUser = Get-ADUser -ldapFilter "(SamAccountName=$UserName)" # #If user exists, exit! if ($CheckUser -ne $Null) { write "User $UserName already exists! Exiting..." write "" exit } # write "Creating $UserName..." write "" New-ADUser -Path "$DefaultUserOu" -SamAccountName "$UserName" -Enabled $true -Name "$FirstName $LastName" -GivenName "$FirstName" -Surname "$LastName" -AccountPassword (ConvertTo-SecureString –AsPlaintext "ChangeMe123!" –Force) -ChangePasswordAtLogon $true # write "Create $HomePrefix\$LastInitial\$UserName ..." write "" New-Item -type directory -path $HomePrefix\$LastInitial\$UserName # write "Setting permissions on the $HomePrefix\$LastInitial\$UserName ..." write "" $acl = Get-Acl $HomePrefix\$LastInitial\$UserName $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$MyDomain\$UserName", "DeleteSubdirectoriesAndFiles, Modify, Synchronize", "ContainerInherit, ObjectInherit", "None", "Allow") $acl.AddAccessRule($rule) Set-Acl $HomePrefix\$LastInitial\$UserName $acl # write "Setting the Home Folder attribute for $UserName" write "" Set-ADUser -identity "$UserName" -homeDrive h: -homeDir "$HomePrefix\$LastInitial\$UserName" # write "...Complete!" write "" #

…and there you have it.  Now, of course, I could have dumped in a lot of other good practice stuff like input validations and things, or other additional neat features, but I’m only trying to demonstrate the core concepts here from our previous posts in this series.  I don’t want to over-whelm the example and make it difficult or — heaven forbid — boring (gasp!) to read.

But please, if you have a better way of doing it, make sure to drop a comment or two and help out others…

Now go create some users!

 

 

Did you like this? Share it:

Tags: , , , , , , , ,