Wednesday, November 19, 2014

Whose password is about to expire?

Working with dozens of different customers, I have seen this request come up a lot, so I came up with a few ways to collect this information and you can modify and run with your own version as required.

Many groups I have worked with have asked for lists of users whose passwords were on the verge of expiring. Here a few of the most common methods I have shared with them:

To get a list of users in an OU whose passwords are older than 30 days, try this in PowerShell. Add desired return fields to the select section as desired:

Get-ADUser -SearchBase "ou=targetou,dc=domain,dc=com" -filter * -Properties * | select Displayname, PasswordLastSet | Where-Object {$_.PasswordLastSet -lt (Get-Date).AddDays(-30)}

If you have a list of login names in a text file for users scattered throughout the directory, you can try this:

Get-Content .\users.txt | ForEach-Object {Get-ADUser $_ -Properties * | select Displayname, PasswordLastSet} | Where-Object {$_.PasswordLastSet -lt (Get-Date).AddDays(-30)}

Sometimes, you get a list of "user names" that is actually a list of email addresses, in which case you can try this (and you can choose your own attribute filter if needed):

Get-Content .\emailaddress.txt | ForEach-Object {Get-ADUser -Filter {EmailAddress -eq $_} -Properties * | select SamAccountName, DisplayName, PasswordLastSet, EmailAddress} | Where-Object {$_.PasswordLastSet -lt (Get-Date).AddDays(-30)}

That should be a good jumping off point. Enjoy!!

"I have the POWER!!" (guess...)

- Peter Trast, MCITP EA, MCITP DBA, MCT LinkIn with Peter

Wednesday, September 10, 2014

Making those one liner scripts

Hey PowerShell users, do you love to script, but sometimes find yourself wishing that you just had a one liner to use instead of needing to copy or remotely execute a .ps1 file?

I was emailing back and forth with some colleagues at work recently, and one of our brilliant engineers had sent out this script to find the domain controller in the "closest" site that had the lowest latency. I don't know if he wrote it (he is certainly capable) or found it, but we all found it very useful:

$ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
$servers = Get-ADDomainController -Filter  {Site -eq $ADSite}
$DCListObject = New-Object psobject
$DCListObject | Add-Member -MemberType NoteProperty -Name HostName -Value $null
$DCListObject | Add-Member -MemberType NoteProperty -Name QueryTime -Value $null
$DCListObject | Add-Member -MemberType NoteProperty -Name Latency -Value $null
$results = @()
foreach ($server in $servers) {
    $DC = $DCListObject | Select-Object *
    $latency = Test-Connection -ComputerName $server -Count 1
    $querytime = Measure-Command -Expression { Get-ADObject -Server $latency.IPV4Address -LDAPFilter "(&(&(objectCategory=Person)(objectClass=User))(sAMAccountName=REMOVED*))" -ResultSetSize 1 -ErrorAction SilentlyContinue}

    $DC.HostName = $server.HostName
    $DC.QueryTime = $querytime.TotalSeconds
    $DC.Latency = $latency.ResponseTime

    $results += $DC
$results | sort QueryTime | ft HostName,Latency,QueryTime -AutoSize

Many remarks were made about the usefulness and coolness of the script, with the addition of one smart alecky response: "It's garbage. Make it one line :-)". This seems to be a running joke here.

Having just spent the last 16 months with a company full of penguin lovers at my last position, I responded with "Challenge accepted ;) maybe", even though I had not been the one challenged. About 8 minutes later (according to my email client), I sent the following back to the group:

$ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name ; $servers = Get-ADDomainController -Filter  {Site -eq $ADSite} ; $DCListObject = New-Object psobject ; $DCListObject | Add-Member -MemberType NoteProperty -Name HostName -Value $null ; $DCListObject | Add-Member -MemberType NoteProperty -Name QueryTime -Value $null ; $DCListObject | Add-Member -MemberType NoteProperty -Name Latency -Value $null ; $results = @() ; foreach ($server in $servers) {$DC = $DCListObject | Select-Object * ; $latency = Test-Connection -ComputerName $server -Count 1 ; $querytime = Measure-Command -Expression { Get-ADObject -Server $latency.IPV4Address -LDAPFilter "(&(&(objectCategory=Person)(objectClass=User))(sAMAccountName=REMOVED*))" -ResultSetSize 1 -ErrorAction SilentlyContinue} ; $DC.HostName = $server.HostName ; $DC.QueryTime = $querytime.TotalSeconds ; $DC.Latency = $latency.ResponseTime ; $results += $DC} ; $results | sort QueryTime | ft HostName,Latency,QueryTime –AutoSize

Worked great!

Two things, though. First, sure it's nice to be able to paste a one liner like this into PowerShell and run it with no need to create, save and possibly copy paste a .ps1 text file somewhere. But, secondly, who wants to try to decipher that hideousness?

In case it is not obvious to the reader, all I did in this case was, mostly, to separate each line in the script from the next one using a semicolon. The result is ugly but condensed to a single line that can be stored in your script repository for copy/paste use at any time. Don't ask your developers to look at it though, unless you enjoy that quizzical-what-kind-of-nonsense-am-I-looking-at expression. One other potential bad thing I noticed was that this one liner consistently ran a little slower than the .ps1 script.

Just goes to reinforce the old saying, "Just because you can does not mean you should."

But sometimes the question of "can" is just more fun.

"So that's your ambition? Script writing?" -- Mr. Fisher
 "Yes, it always has been." -- Billy

- Peter Trast, MCITP EA, MCITP DBA, MCT LinkIn with Peter

Monday, September 8, 2014

Windows "unmovable" files CAN be moved

I recently had the pleasure of trying to shrink a volume to allow enabling of BitLocker, only to be informed that I had 0 megabytes of space available for shrinking. Since the 278 Gigabyte drive had about 90% free space, this was a bit shocking, especially considering that I had just installed the operating system a few days earlier. But don't punch the screen before you have a gander at the rest of this post.

I am not going to delve into why this happens, or how to prevent or manage this completely at this point (since I have not figured all of that out just yet), but I did manage to come up with a procedure to open up the last 300 Megabytes of the disk so that I could complete my BitLocker install.

Once you have gone into the Disk Management interface to query available Shrink space, or have used DISKPART "shrink querymax" (see a full explanation of DISKPART usage elsewhere or message me for help), an event will be recorded in the application log regarding the last unmovable file. If you filter the log for an Event Source of Defrag, you will find a recent entry like this:

"A volume shrink analysis was initiated on volume (C:). This event log entry details information about the last unmovable file that could limit the maximum number of reclaimable bytes.

 Diagnostic details:
 - The last unmovable file appears to be: \Windows\CCM\ServiceData\Messaging\EndpointQueues\ClientRegistration\00000001.que::$DATA
 - The last cluster of the file is: 0x45a9698
 - Shrink potential target (LCN address): 0x455982
 - The NTFS file flags are: ----D
 - Shrink phase: <analysis>"

As you can see, the location and name of the file is identified. If you browse to this location in explorer and try to cut the file from it's current location and paste it on another physical drive (a "move"), you will get a popup telling you the name of the service preventing it's move, i.e., in this case, "SMS Agent Host". If you stop the service, you can move (cut and paste, not copy) the file to another physical drive and then move it right back again and restart the service. This will almost always use the first open space nearest the beginning of the disk and create more free space at the end of the disk, where the shrink occurs.

Now you can query the available shrink space again using either Disk Management or DISKPART, and if the space is still too small, review the event viewer again and continue to move files and restart services as needed until the available space is achieved. Occasionally, you might find a file locked by some system process that will be trickier to move, as I did. One file I found was locked by Windows Explorer. In this case, I opened Task Manager and killed the Explorer process, and then opened a New Task from the Task Manager menu to run a command prompt and performed the move from there. After the file is moved off and back onto the original drive location, simply open a New Task from the Task Manager menu and type in "explorer" which will revive the graphical Windows interface.

If you are especially unlucky, you might find a file that is truly difficult to move, like

"\System Volume Information\{2d100ba4-2cad-11e4-825d-3417ebae23dc}{3808876b-c176-4e48-b7ae-04046e6cc752}::$DATA"

in which case you will have to work on file permissions to get that moved, if it is even possible to move with Windows running. If not, you might need Safe Mode or might even need to connect the disk to another system instead of booting up that system.

In any event, most files that are declared "unmovable" can be moved with a little fancy footwork. The files are not "unmovable", just locked in their current location by a running service, which would be a much better description in the event (Microsoft tech writers, are you listening?).  :)

So don't believe that annoying little remark in event viewer and make that file obey your will!

"You cahn doo eet!" -- Rob Schneider

- Peter Trast, MCITP EA, MCITP DBA, MCT LinkIn with Peter

Thursday, August 28, 2014

Try something hard "for the win"

I recently moved on from an amazing company that is providing a superior service to the planet, though they have not really been recognized for it ... yet. Most people don't even know what a CDN is, even though most of us access data through one every day. That technical environment is very unique, and there are not many jobs and skillsets that can prepare you for life in this most original of  infrastructures.

So I thought maybe I should spend some time working there, if they would have me. Forget the fact that my Linux experience, necessary for about 99% of the work, was almost non-existent. Never mind that I had never worked for a CDN. And let's not focus too much on the fact that I am primarily a Microsoft technologist. I wanted a challenge, they wanted fresh, raw talent, and boy did we have some fun.

I spent months learning the most basic tasks, endeavoring to become an "expert" in as little as 6 months. I would like to tell you that I was a superstar, experiencing the kind of success that typifies most of my IT career. But, truth be told, I often felt surprised that I had not received that dreaded notification that my "services were no longer needed". That is not to say that I was horrible at my job, but focusing on a variety of new skills while surrounded by world class engineers and architects can skew your self-perception a bit and shake your confidence. Still I held on for 16 months because, hey, I really liked the company, I still believe in it, and I wanted to participate in what I believe is it's imminent breakthrough in the market. My customers seemed to really like me, despite my own (in my mind at least) shortage of technical skills but, more likely, because of the amazing team support I received... ok, plus maybe some of my customer service skills, the only real asset that I felt I had added to the equation.

But then the call of the "Windows" pierced my penguin-y existence, and I got that offer that just could not be overlooked. Go back to my core skillset, the one I love so much and, I humbly confess, I am so much better at when compared to bears of averageness. Be well compensated and have the chance to be a "guru" again. How could I resist?

But I would not trade my fire trial in the CDN world for anything. I added a big lump of open source knowledge to my bag of tricks (and I really LOVE some of those tools now), and I got a fresh perspective on what it really means to work hard. Most of the time, working in my base, I know 75-90% of what I need to know, and I just merely need to design solutions around that and implement them with minimal research. But spending almost a year and a half in constant "ask and learn" mode taught me that it's really nice to be in your own wheelhouse.

I surely love new challenges and adventures, and no doubt I will keep a weather eye open for some other unique and possibly "crazy" opportunity. I consider it a major success that I survived this intense experience and might have even contributed some value along the way. It feels like a win for both the employer and me. I tried something really hard and didn't fall flat on my face, even though I often felt like I was running at full speed down a steep hill.

But it's nice to be "back home", and I think I will hang out in my "comfort zone" for awhile...

Have you ever tried something you probably had no business attempting? :)

"Why is the rum always gone?" -- Captain Jack Sparrow

- Peter Trast, MCITP EA, MCITP DBA, MCT LinkIn with Peter