File Share Woes

As sys admins, we all eventually hit the problem of inheriting file shares that were set up by years and years worth of SA’s who all felt their way was the best way to do it. I have a firm belief that any way you do it is fine, as long as you do it that way consistently. Eventually, you will find a file share where someone gave users Full Control to a file share or thru NTFS and those users modified the ownership of the files and took admins away. Then those people left and now you nor anyone else can access those files

Or, even worse, you got hit by a virus that stripped all the permissions away.

As with everything, there’s a lot of ways to fix this. You’ll first have to take ownership of the files and then reset the permissions back to default inheritance. You NEVER want to manage permissions on subfolders if you don’t have to.

The easy way is to use takeown and icacls:

takeown /f * /a /r
icacls * /inheritance:e /t

That works great, until it doesn’t. Takeown has some limitations which you’ll eventually run into. You’ll likely start getting random memory or caching errors. To fix, that use SubInAcl

Be very careful with subinacl. It’s a very powerful too and you could cause yourself a world of hurt with it.

subinacl /file "PATH" /setowner=Administrators <-- to claim ownership of the root
subinacl /subdirectories "PATH\*.*"  /setowner=Administrators <-- to claim ownership of everything else

icacls * /inheritance:e /t

That’s it!

Powershell: List all Mailboxes and Export

In a previous post I covered how to do this with Distribution Lists. Now I want to do the same thing for user mailboxes, however the code ended up being a little bit different since I want to key off of Primary SMTP Address vs. just the name. Since the email address has an @ sign in it, the code changes because it exports differently.

This particular code snippet gets all Mailboxes in Exchange and dumps them to a file. Easily modifiable for other purposes if you need to:

foreach ($item in $(get-mailbox -resultsize unlimited)){$results+=[string]$item.PrimarySMTPAddress}
$results|out-file c:\migration\userout.txt

Let’s break this down a little bit:

$results=@() <== explicitly creates an array for population later

$results+=”smtp” <== because of what I want to do with the export file later, I want a header in this file. This line just creates the initial header.

foreach ($item in $(get-mailbox -resultsize unlimited)){$results+=[string]$item.PrimarySMTPAddress} <== Several things going on in this line. I like combining statements into as little possible code as I can, so this one can be confusing if you don’t know how to look at it

  • foreach (blah in blah){blah} <==typical for each statement that does the {} for every item in the list
  • $item in $(get-mailbox -resultsizeunlimited) <== Pulls every mailbox with no limitations and puts them into the array

$results+=[string]$item.PrimarySMTPAddress <== Pulls the Primary SMTP attribute from every mailbox and adds it into the array defined above. Had to convert it to a string so that it would export in the correct format

$results|out-file filename.txt <== Outputs the results of the array into a textfile

Scripting ADMT from the command line

ADMT from the command line has a ton of options, but it does make it nicer if you need to script migrations or just want to run thru things quickly. It also helps tremendously that ADMT 3.2 has a bug that you can NOT use an include file when you want to ADMT groups. So you either have to specify them all manually or use it from the command line.

Which introduces yet another bug that you can NOT ADMT over sidHistory unless you have ADMT installed on a domain controller. In most environments putting ADMT on a DC would violate several standards and isn’t really a good practice. BUT if you need to script your ADMT group migrations and want sidHistory, you have to do it on a DC, so there you go.

But if you want do an ADMT group migration from the command line you can type admt group /? to get an example of all the things you can set. You can also build an options file and specify that in your command as well. Either way works fine, although if you’re going to be migrating something repeatedly an options file might be the best way to go.

One thing I’d like to note here is that I’ve also set my ADMT to NOT exclude any attributes, following the guide here:

So when you ADMT a group, unless you exclude the Exchange attributes, it WILL migrate it as a DL. However, that DL will still be stamped with the old version of Exchange to fix that after you migrate the groups, run this command:

get-distributiongroup –resultsize unlimited|set-distributiongroup –forceupgrade

Once you do that, make sure you exclude the exchange attributes the next time you migrate or you’ll have to do it all over again!

Let me give the command I’m using here and then we’ll deconstruct here:

admt group /SD:"" /TD:"" /TO:"Staging/AMER" /UGR:YES /FGM:Yes /CO:MERGE /gx homeMTA,mailnickname,msExch*,msRTCSIP*,msSFU*,proxyAddresses,showInAddressBook,targetAddress /UMO:YES /F:"d:\migration\groupout.txt"

  • /SD <== Sourcedomain FQDN
  • /TD <== Targetdomain FQDN
  • /TO <== Target OU. This one is a little tricky. It doesn’t want the CN or DN. It wants the OU structure from the root. So if your domain is and off the root you have an OU called Staging and have another OU under that called AMER, you would use Staging/AMER here
  • /UGR <== Update Group Rights
  • /FGM <== Fix Group membership. This is the important one if you want to make sure that DL’s and groups are updated with the appropriate members
  • /CO <== Conflict Options
  • /UMO <== Update Previously Migrated Objects
  • /F <== Include file
  • /GX <== Exclude Exchange/LYNC/NIS related attributes

Then just script and execute and you’re done!

Powershell: list all DL’s and export

The next several posts are going to be quick code drops for me. I’m working on a few process to export everything from one GAL and import it to another one. Partly using ADMT (scripted) and partly using Powershell with the Exchange EMC.

This particular code snippet gets all Distribution Lists in Exchange and dumps them to a file. Easily modifiable for other purposes if you need to:

foreach ($item in $(get-distributiongroup -resultsize unlimited)){$results+=$}
$results|out-file c:\migration\groupout.txt

Let’s break this down a little bit:

$results=@() <== explicitly creates an array for population later

foreach ($item in $(get-distributiongroup -resultsize unlimited)){$results+=$} <== Several things going on in this line. I like combining statements into as little possible code as I can, so this one can be confusing if you don’t know how to look at it

  • foreach (blah in blah){blah} <==typical for each statement that does the {} for every item in the list
  • $item in $(get-distributiongroup -resultsizeunlimited) <== Pulls every DL with no limitations and puts them into the array

$results+=$ <== Pulls the name attribute from every DL and adds it into the array defined above

$results|out-file filename.txt <== Outputs the results of the array into a text file

Powershell Array

I don’t know why, but I have a huge problem dealing with arrays in powershell, especially when I want to export the results into CSV. So this one is for me 🙂

The below script reads an input file for a list of server/computer objects. It then goes thru each line and does a gwmi call to pull the OS version (I built this script so that I could do a dump out of DNS and check each entry for the OS it was running).

Then it adds the results to an array, then adds THAT to another array since you can’t do an append on export-csv prior to PS 3.0. Then outputs it all in a nice format for you.

$erroractionpreference= "silentlycontinue"

$Inputfile=get-content c:\computers.csv
$out= @()


foreach ($Compname in $Inputfile){

$OSVer=gwmi win32_operatingsystem -computer $CompName

$OutObject= new-object psobject
 $outobject|add-member noteproperty Name $compname
 $outobject|add-member noteproperty OSVer $
 $out += $outobject


$out|export-csv $outfile -notypeinformation


ADMT and Exchange attributes

Using ADMT 3.2 and wondering why you can’t see your Exchange attributes to exclude? There’s an easy fix (although make sure you really need to enable them, as this can cause your migration some problems).

Create a text file and name it ADMTExclusions.vbs. Save it in c:\windows\syswow64.

Put this in the file:

Set objMig = CreateObject("ADMT.Migration")

objMig.SystemPropertiesToExclude = ""

Now go to an elevated command prompt and browse to c:\windows\syswow64. Run it with:

cscript admtexclusions.vbs.

There you go!

Installing Windows 8 with an SSD


I recently purchased a new Windows 8 laptop and rebuilt it, copied all my stuff over, etc. It had a relatively small ~25 GB SSD drive and while it wasn’t slow to boot and login, it wasn’t that fast either. In my search for the “7 second” boot time, I came across a bunch of articles and suggestions and ended up rebuilding my laptop several times to finally get the extremely fast start time. After doing all that I found yet another tip to make it even faster, but decided it wasn’t worth yet another day to rebuilt it yet again.

First, let me give you the links I found, then I’ll give you an outline of the process I followed. How you do it will depend on the size of your SSD and how much pain you’re willing to go through.

The best guide for implementing/using an SSD with Windows 8:

Using symbolic links to move user profiles over to your main drive:

First off, I tried to cheat and do a Windows Easy Transfer to get my data and profile from my old machine to my new one. It didn’t end up working for me because WET sees your new SSD drive as the C:\ and won’t do the restore because it thinks you’re out of space. I ended up having to copy everything over and setting everything up manually. Just be aware!

So in my case I had a 25GB SSD and a 1TB HDD. I wanted the OS on the SSD (C:\) and everything else on the HDD (D:\). Because my SSD is relatively small I elected not to create a Rapid Start partition, but it’s the last piece that is supposed to make the OS super fast.

When you install the OS make sure you delete all the partitions on both disks and follow the 1st guide above fairly close. Here’s where I deviated:

  • I made a very small pagefile and moved it to the D:\
  • I elected not to keep my user profile on C:\ due to the space limitations. I also didn’t want to just move pictures/videos/etc to d:\, so I used symbolic links (more on that in a bit). Note that this has caused me a few issues, but nothing I haven’t been able to get around.
  • I left the UAC on. I’ve been burned by viruses before and keeping the UAC on is worth the annoyance for me

In addition to moving my profile using the second link I provided above (symbolic links), I also moved some other Windows directories like SoftwareDistribution and Temp. This clears up some non-essential files that can severely impact how much disk space you have. I went from having less than 2GB free on the SSD to about 9GB.

I found other suggestions for how to move user profiles to the other drive, including sysprep, but that gave me a ton of issues. I felt using the symbolic link was the cleanest way to go. Note that I also tried moving ProgramData over, but as others suggested it would it gave me a ton of problems with the Metro interface.

I tried changing the default program files location in the registry, because I was tired of changing it when I installed apps, but other things got flaky when I did that. IE10 stopped working completely. I don’t use IE normally, but I do like having the builtin browser working successfully, especially given how much MS ties into it.

That’s about it. My boot time went from about 1 minute before to maybe 5-7 seconds after. It wakes from sleep almost instantly. I haven’t particularly noticed that the shell itself is faster, but this is a new laptop that is much faster than my old one, so it’s hard to judge.

Do you have any other suggestions on how to speed up Windows 8? Any other good tips of items to move to the local disk? Let me know in the comments!