Powershell – That torrid vbScript affair – Part 4

Powershell

The keyboard is covered in sweat, there is heavy breathing in front of the screen.  “Quick disconnect the LAN cable before she finds out!”

“Dear Diary.

I should be ashamed.   I am having an affair with vbScript and my Mistress Powershell suspects something is up.   There were a few times this week I accidentally used a ‘ instead of a # to comment.   This is getting dangerous…”

 

And so I promised.  Today we’re going to get Loopy and see a vbScript loop vs a Powershell loop to make the task of converting easier.   For although many of us love working in Powershell, we must tip our hats in respect to vbScript and it’s amazing established library.

Having said that, we shall RAID and PILLAGE for code to rewrite… “Yeeeaaarrrrrhh!  AHAR!”

So a quick look and one of the most common loops is the For Next where you establish a range of information to step through, going FOR the NEXT one as you encounter it, and well do SOMETHING.

in the magical Land of vbscript here is a very basic looking “For” loop.

For This = 1 to 20

wscript.echo This

Next

in Powershell that would look like this

FOREACH ( $THIS in 1..20) {

Write-HOST $THIS

}

There are some SLIGHT differences in the Syntax ( Parentheses about the code in Powershell for one ) but if you look at each, they are very similar.   They both specify a Range of values and simply execute a block of Code.   VbScript requires the “Next” indicate the end of it’s particular FOR loop but the functionality is very similar.

Here’s where the two are VERY much the same (and thus where translation becomes a little bit easier)

Here is a script borrowed from the TechNet Archives (Free to download) which simply lists the Services on a PC

strComputer = "."

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")

Set colRunningServices = objWMIService.ExecQuery("Select * from Win32-Service")
For Each objService in colRunningServices 
Wscript.Echo objService.DisplayName & VbTab & objService.State
Next

My first reaction was “AIHAGHAIHGHAIHGHAHGHAHHG!!!!” with my hands flailing in the air in panic.

Then I looked at that last bit. That looked SUSPICIOUSLY like I was staring at

FOREACH ($ObjService in $ColRunningServices) { Do stuff }

That’s because I was. vbScript can deal with Objects too (not quite as elegantly as Powershell but it can.  Understanding this helps you see a loop like that and realize some of the code is VERY similar

So that same code from vbScript translated to Powershell could look like this

$strComputer=’localhost’

$colRunningServices=GET-WMIOBJECT -namespace ‘root/CIMV2’ –query ‘Select * from Win32-Service’

ForEach ($objService in $colRunningServices) {

  Write-host $objService.DisplayName, $objService.State
}

Ok the format isn’t EXACTLY the same but this session is about LOOPS. And if you stand back and pause, you’ll see the slight differences and also the similarities between the two loops.

And that’s not really all that difficult to translate between the two.  It’s just about the Syntax.  So next time we’ll see the other loops and hopefully not get TOO loopy and lose our minds.

 

Just Remember, The Power of Shell is in YOU

Sean
The Energized Tech

Powershell – Audit the Exchange Server 2007 for Mailbox Access

Powershell

An interesting task to go about today.

“How do I tell if a User has rights to another user’s Mailbox?”

In Exchange 2007, in the new Console, an Enterprise Exchange Admin can now EASILY grant FullAccess and SendAs rights to users.

the problem comes up that after a few years, well you’re going to wonder WHO is able to access WHAT?   Especially with staff changes and Administrator switches.

But thankfully with Powershell, this is a Breeze!

We have a commandlet called GET-MAILBOXPERMISSION.  It ties right into GET-MAILBOX too.

So watch this little trick.

GET-MAILBOX john.smith | GET-MAILBOXPERMISSION | where { $-.Name –like ‘*Joey.Admin*’ }

That one line will tell you if “Joey.Admin” has rights (any rights) on John.Smith’s mailbox.

Now it gets cooler.  Maybe “Joey.Admin” got fired and we need to make sure he doesn’t have access to other mailboxes.  Or better yet.  Perhaps “Joey.Admin” didn’t LISTEN to his boss and was casually granting himself full access to corporate mailboxes abusing his admin rights.

Wouldn’t you like to EASILY know?

Same command but don’t get specific

GET-MAILBOX | GET-MAILBOXPERMISSION | where { $-.Name –like ‘*Joey.Admin*’ } | Select-Object $Identity

Now you have all the Mailboxes “Joey.Admin” had rights on (even if he wasn’t SUPPOSED to have rights on them)

Fine.  So we figured out the mess Joey left.   Wouldn’t it be nice if there was an EASY way to clean it up after we Demote Joey to Janitor?

Piece of cake in Powershell

GET-MAILBOX | GET-MAILBOXPERMISSION | where { $-.Name –like ‘*Joey.Admin*’ } | REMOVE-MAILBOXPERMISSION –user ‘DOMAINJoey.Admin’ –inheritancetype ‘All’ –AccessRights ‘FullAccess’

 

I agree that’s a mouthful to type, but that will go through the list and prompt you to remove Joey.Admin from the permissions.  If you want to have him removed from all those mailboxes, just choose “Yes to All” when prompted. 

This will work for anywhere from 1 to however many mailboxes you have.  All in one line.

The Power of Shell is in YOU

Sean
The Energized Tech

Powershell – Show Group Membership in Server 2008R2

Powershell

A colleague contacted me yesterday. 

He said “Oh Great and Wonderful Wizard of the Shell, bequeath to the me the guidance to navigate the mystery that is Powershell so that I can easily produce a report of just WHO is in my Groups…”

Well no, he didn’t say it QUITE that way.  It was more, “Sean, you know Powershell, can we easily pull out a report, something in CSV or Excel that show’s members of Groups in Active Directory?”

The only tricky part about that question was this.  “Would you like that in one line or two?”

In truth, thanks to the new Active Directory Modules in Server 2008R2, life for the new Network Administrator in the Enterprise just got so much better thanks to GET-ADGROUPMEMBER

All you need to do to list members of a Group in Active Directory is

GET-ADGROUPMEMBER ‘Group Name’

Done.   So You need to audit your Domain Admins or Enterprise Admins?  Piece of cake!

GET-ADGROUPMEMBER ‘Domain Admins’

GET-ADGROUPMEMBER ‘Enterprise Admins’

How about a custom group you made called “Uber Secret Stuff We Won’t Share”?

You guessed it

GET-ADGROUPMEMBER ‘Uber Secret Stuff We Won’t Share’

Need that in something Excel can use?

GET-ADGROUPMEMBER ‘Domain Admins’ | EXPORT-CSV C:ListOfPeople.csv

Now of course this may pull down too much information.   Generally we just want some basic details, Like Name, SAM Account, Possibly the DN.  Patch in a SELECT-OBJECT (which allows you to “SELECT” which “OBJECTs” you want from the PIPELINE from the previous CommandLet.   Then pass it along or view it.

GET-ADGROUPMEMBER ‘Domain Admins’ | SELECT-OBJECT Name, DistinguishedName, SamAccountName | EXPORT-CSV C:ListofPeople.csv

Now this is all fine, but I prefer making this into a useful Function I can add to my $PROFILE.  So let’s do that.   Instead of typing in all this, let’s make this into a Function that could be reused easily

function global:GET-GROUPAUDIT($GroupName, $Directory) {

#
# Check for Directory name.   If not given Default to the C:Reports folder
#
if ($Directory –eq $NULL) { $Directory=’C:Reports’ }
#
# Build $Filename for output.  Strip spaces from GroupNames for the
# Filename.   Add Default Directory to Path
#
$Filename=$Directory+””+$Groupname.Replace(‘ ‘,’’)+”.csv”
#
# Run GET-ADGROUPMEMBER in the default domain, Select three Objects
# Name, DistinguishedName, SamAccountName
# Export the results to a CSV file
#
GET-ADGROUPMEMBER $GroupName | SELECT-OBJECT Name, DistinguishedName, SamAccountName | EXPORT-CSV $Filename

}

Now this is a very basic function that “Assumes” you’re goinig to type in the Group name and the Directory.   But what it means if you need to report this on a regular basis?  Add that function to your $PROFILE, then in your Powershell Session you can type in

GET-GROUPAUDIT ‘DomainAdmins’ C:Reports

Or easily just pipe in a list of Groups to Query on a regular basis.   This Function has also been setup to do two slightly smart things.  One it will at least ASSUME a folder called C:Reports if you don’t type it in.  Second it will create a .CSV file matching each Group Name.

There you have it.   It wasn’t hard to play with with and even easier to build on!

The Power of Shell is in YOU

Sean
The Energized Tech