Scripted Home Folder Management with PowerShell Pt. 2

2017-07-27T00:01:07+00:00 September 5th, 2012|Uncategorized|

In this post, I’m following up on Part 1 of this series where I showed you how to create users (and set a few attributes) the basic way with Powershell.  Now, I’m going to show you an easier way to create users thanks to the new(ish) Powershell modules that came along in Windows Server 2008 R2.  In the up-coming parts of this series, we’ll continue on to Home Folder creation/management concepts and automation.  But for now, let’s get that user created…

To be honest with you, I have to admit that most of the time when I’m building a script loop and just need an easy output that looks nice, I’d just do the DSAdd tool like this:

dsadd user "cn=Jeremy Pavlov,ou=Demo,dc=CoretekServices,dc=local" -samId JPavlov -disabled no -fn Jeremy -ln Pavlov -pwd ChangeMe123! -mustchpwd yes

…but the future is here, and the future is PowerShell; and you and I have to get over it.  Powershell gives us better portability, variable management, etc., etc…  So onward and upward. 

And with recent versions of Windows 2008 R2, Microsoft provides the new “ActiveDirectory” module; making user creation/management activities as easy to do as the DSAdd/DSMod tools.  Here’s what I mean…

Open a Powershell session, and import the ActiveDirectory module like this:

Import-Module ActiveDirectory

Note: You need to have network access to an Active Directory server running AD Web Services for this module to work. 

Loading this module is the equivalent of launching the “Active Directory Module for Windows PowerShell” option on Windows 7 and Server 2008, but if you’re scripting you’ll want to make sure you load the module explicitly.  And, as a result, you have a ton of new AD tools available to you. 

You can get a good look at the majority of the new AD tools by using this command:

Get-Command *-AD*

Finally, using the New-ADUser command, we create that user with what is pretty much the equivalent of the DSAdd above (I used the same options to help clarify):

New-ADUser -Path "ou=Demo,dc=CoretekServices,dc=local" -SamAccountName "JPavlov" -Enabled $true -Name "Jeremy Pavlov" -GivenName "Jeremy" -Surname "Pavlov" -AccountPassword (ConvertTo-SecureString –AsPlaintext "ChangeMe123!" –Force) -ChangePasswordAtLogon $true

And that’s it!  You have a new user with your standard attributes set correctly.  I like this one-line method because it looks much cleaner when you are building import scripts that must be distributed to other folks, or when you want to insert some other command between each line (if you’re looping), etc.; it’s neat.

On a side note, there’s also a way to read in the contents of a formatted CSV, and pump it into the New-ADUser command; but my goal here is to show you concepts that ultimately can be combined into an multifaceted script.

Next time…  Home Folder creation and permission assignment.  See you then!



Scripted Home Folder Management with PowerShell Pt. 1

2017-07-27T00:01:07+00:00 August 29th, 2012|Uncategorized|

I’ve been doing tons of scripting for the project on which I’m working lately.  And I thought it’d be cool to spend a few posts in a row covering a few base elements of PowerShell-based user and Home Folder management, and build up toward a script for user and folder creation/deletion that you can easily use. 

I don’t intend to get fancy with this; in fact, I intend to make is simple as possible, and maybe kick around a few alternative methods to do the same tasks.  My goal is not to teach PowerShell, but to show you you can script these things easily.

So join me on the journey!  But let’s get there in small steps.  We’ll start at the start, with user creation.  Open a PowerShell session, and let’s get to it…

In order for this article series to work, I have to make some assumptions: I’ll assume you have the proper rights, a test environment, the proper PowerShell modules, and a Windows 7 or Server 2008 R2 computer.

For this first method in Part 1, we are going to show you how to do it with just native Powershell, using the ADSI provider, without any additional Powershell modules.  It’s like learning how to do the work on paper before you use a calculator…  😉

First, set up a variable that opens an LDAP connection to the server, using the ADSI provider (note, “LDAP” is case-sensitive) and specifying the OU where we’ll be creating our new User object:

$MyConnection = 

Next, set up a variable that defines what you’re creating, along with a few critical attributes:

$MyObject = $MyConnection.create("User","cn=Jeremy Pavlov") 

Finally, the command to make it happen:


…and with that, the user is created in a “disabled” state.  So let’s fix that and set a password, using the same object and connection calls:


But, as you may or may not expect, the act of setting the password in the previous step also clears the requirement for the user to change the password at first login… but we definitely want the user to do that.  So let’s set it back with one final step:

$MyObject.pwdLastSet = 0

Okay, okay, I know what you’re saying, “…Man, that’s alot of work…”  And I’ll admit,this is the hard way.  So I’ll show you some easier ways in the next post.

(Updated 20120903; fixed syntax typos, split some content to next week’s post)

Next time…  A couple easier creation options…  See you then!



How to check the VMware Tools version across your Windows Server 2008 R2 farm…

2012-06-20T22:40:00+00:00 June 20th, 2012|Uncategorized|

I was on a conference call today where someone asked if the server administration team could quickly get a “read” on the VMware Tools version across the server farm.  An ESXi upgrade was being deployed and the team wanted a quick way to see what VMs needed to catch up with the deployment.

Fortunately, I had a bunch of PowerShell snippets lying about that would fit the bill nicely.  Of course, there are a few different ways to accomplish this, depending upon which resources that you are permitted to access; but using PowerShell in a loop with a list of your server names is a quick and easy way to get it done.

So first, a little set up…  Imagine that we are inside a PowerShell script, in a foreach loop (or a function called by that loop) that is calling each computer (our Windows 2008 R2 servers) in a list.  At the time you hit this snippet of code, the current server name in the loop is in the variable $ComputerName, and the output file for the report is $outfile


    write "" | Out-File $outfile -append
    $vmtoolstatus = Get-WmiObject -class Win32_Product -computername $ComputerName | Where-Object {$_.Name -match "VMWare Tools"} |select Name,version
    if ("X$vmtoolstatus" -eq "X")
      write "VMware Tools **NOT** found." | Out-File $outfile -append
      write "WMware tools presence/version info:" | Out-File $outfile -append
      $vmtoolstatus | Out-File $outfile -append


All we’re really doing here is to query the product list for the tools, and if present report the version. And the result look something like this for each item in the loop:

WMware tools presence/version info:
Name                                                        version                                                  
----                                                        -------                                                    
VMware Tools                                      

Simple, but effective and functional. 

I hope it helps!



Powershell – Handling Reserved Characters in a Password

2017-07-27T00:01:08+00:00 February 15th, 2012|Uncategorized|

Recently I was using PowerShell to update records in a SQL database.  Unfortunately for me, the SQL credentials contained a dollar sign ($); which is a reserved character in PowerShell. 

Originally, building and sending my connection string (including the password within the string as usual) resulted in a failure to log in.  Even after some inclination that the dollar sign might be problematic, and encapsulating it in single quotation marks within the connection string, the login still failed.

After confirming that the connection string was indeed valid (through other means), the trick that ultimately worked in PowerShell was to set the password to a variable as a literal string (meaning, wrapped in single quotes) and then pass the variable along with rest of the connection string.


$psw = 'dbp$$wd'
$sConnString = "Driver={SQL Server};Server=;Database=DBName;Uid=db_user;Pwd=$psw;"


This approach will apply to other special characters as well. 

Good luck!



Finding Rogue KMS Servers in the Enterprise…

2017-07-27T00:01:08+00:00 February 8th, 2012|Uncategorized|

In larger Enterprises with Microsoft-based infrastructure, it’s highly likely that the licensing for the Windows 7 workstations will be based on the Microsoft KMS model.  If you don’t already know, this means you run servers in-house that register themselves into DNS as license providers, and Windows clients will learn of them (and become affiliated with them) to get a license, rather than contacting Microsoft themselves across the Internet.

Unfortunately, one problem that can occur is that someone who has access to the Microsoft license codes (like an I.T. worker, developer, etc.) might accidentally install a KMS license on a server that is not intended to be a KMS server.  And when a KMS license is installed, the server doesn’t know any better; and dutifully registers its KMS capability with the internal Active Directory based DNS as a VLMCS SRV record. 

Recently, I ran into a situation where I needed to hunt down and eliminate some accidentally rogue KMS servers that had cropped up across a large infrastructure, and be able to re-check at regular intervals.  While I originally wrote the script as a bash shell script for Linux, I re-wrote it into PowerShell recently for someone who asked, and I thought I’d post the new version here.

Mind you, this is a stripped-down version of the script, but it includes all that is needed to run the check manually for a hierarchical DNS infrastructure (although you may wish to strip out components if you just want to check the parent domain). 

Copy the contents below, paste them into a PowerShell script file (*.ps1), change the variables at the top… and have fun!


# Change the following 3 variables as needed.
# This script will loop through the subdomains, checking for KMS servers in each
# subdomain, and then at the parent domain.
$subs = @("subdomain1", "subdomain2", "etcetera")
$parentdomain = mydomain.local
$outfile = "checkKMS-Results.txt"
write "KMS check report..." | Out-File $outfile
write " " | Out-File $outfile -append
write "The only valid KMS servers are at the $parentdomain, as follows:" | Out-File $outfile -append
write "KMS1, KMS2, KMS3" | Out-File $outfile -append
write " " | Out-File $outfile -append
write "There should not be a KMS server at any of these locations:" | Out-File $outfile -append
foreach ($item in $subs)
  write "Checking subdomain: $item"
  $result = nslookup -type=srv _vlmcs._tcp.$item.$parentdomain. |findstr /C:"_vlmcs" /C:"svr hostname"
  if ("X$result" -eq "X")
    write "No registered KMS server in $item" | Out-File $outfile -append
    write "***KMS FOUND at this location: ***" | Out-File $outfile -append
    write $result | Out-File $outfile -append
write " "  | Out-File $outfile -append
write "On the contrary, the following should be valid KMS servers:" | Out-File $outfile -append
$result = nslookup -type=srv _vlmcs._tcp.$parentdomain. |findstr /C:"_vlmcs" /C:"svr hostname"
$result | Out-File $outfile -append
write "...Done!" | Out-File $outfile -append




Load More Posts

Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: `POST` resulted in a `400 Invalid instrumentation key` response: {"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Invalid instrumentation key"}]} ' in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 Stack trace: #0 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response)) #1 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #2 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promi in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113