You just brought up a Powershell prompt to navigate to the Exchange install folder, or perhaps the Exchange scripts folder.  Lets see… cd \program[tab complete].  cd Micro[tab].  ”dir”  cd Exch[tab].  ”dir” cd v[tab]….

And you think to yourself, “I’ll have that path memorized one of these years…”  But wait! Those smart Exchange developers knew you would probably need to go here often, so they went ahead and put those paths in the $exbin and $exscripts variables.

[PS] C:\> cd $exbin
[PS] C:\Program Files\Microsoft\Exchange Server\V14\bin>

-or-

[PS] C:\> cd $exscripts
[PS] C:\Program Files\Microsoft\Exchange Server\V14\scripts>

You’re welcome. :-)

-Robbie

Be Sociable, Share!

This is a topic I’ve thought about posting for a long time.  It seems almost like common sense, and I didn’t want to insult anyone, but the more I’ve thought about this, the more I’ve realized that this is an art.  Or perhaps a skill.  Maybe even an intuition.

What the hell am I talking about?  Googling.  You know, your server just blew up.  10,000 users can’t get their email.  All you see is a stream of errors in the event log, and at the same time, end users are yelling at you because they *have* to send this super important file using a non-guaranteed delivery mechanism (email).  Managers are calling you on the phone, sending you an IM, your pager is going off, and you’re getting urgent tickets in your ticketing system.  What to do?!?!?!!11??omgwtfbbq!!

Well first of all, take a chill pill and be thankful you don’t have a flesh eating bacteria.  Yeah, it could be worse.  Seriously.  You always want to poke around the system for obvious stuff (is the disk full?  what was the first error event in the event log? was another admin logged in and now you aren’t hearing a peep out of them?), but you know what, the most simple brain dead way to help track down a problem is to just google it.

Now here is what separates experience from omgwtfbbq?!!11!!.  What do you google for?  This is almost basic troubleshooting 101.  Don’t just search for “email broken, halp”.  You need to at least try and find the source of the issue, or if your logs don’t go back that far, just search for the event ID and source of whatever you do see.  Or if a system-generated error message shows up, search for that, because you KNOW that a system-generated message will be the SAME on every other system in the world running that same version.  And thats what you want to find, other people running the same software, who have seen the same problem.  If the search results are too broad, add some additional keywords that are relevant to the problem.  If you suspect it could be a bug, limit your search to the vendor’s website only.  For example, add site:microsoft.com to your search query.  Over time you will start to see the same blogs or message boards pop up, so you will know which ones are likely to have useful information.  Even if you don’t find the exact answer, it will at least get you thinking about things you may not have realized were relevant at first.

Remember that search engines are just a tool, and although rare, it *is* possible that you are the first person to have a particular problem, although probably not.  I can’t tell you how many times someone has come to me with a problem that they’ve been working on forever, and I typed in google, word-for-word, what that person just told me, and the answer was the first result.  Don’t be that guy.  GIYF!

-Robbie

 

Be Sociable, Share!

Late last year, Apple released an updated document detailing how to manage Macs in an Active Directory environment.  You can either add an Open Directory server to the mix, which is another LDAP directory (sorta like AD, except for Macs), or you can just take the Apple specific “schema” modifications in Open Directory, and just apply them to AD (this is called extending the schema).  By the way, an LDAP schema defines what types of attributes are allowed to be stored, such as usernames, computernames, phone numbers, etc, but that’s really way out of scope of this post.

Anyway, even though Apple was nice enough to provide that document (grab it here: http://training.apple.com/pdf/wp_integrating_active_directory.pdf), they didn’t go so far as to *give* us the schema (ldif) file.  They make us create it on our own.  Ugh, really, Apple?  Their argument is that if we are forced to create our own LDIF file, then we’re sure to capture the exact differences between our AD and Open Directory (OD).  That is sort of a valid argument, but having gone through the process of creating that LDIF file, the instructions are so specific, that it appears everyone will end up with exactly the same file, so why didn’t they just give it to us in the first place?  But I digress…

Anyway, the document is well written and easy to follow, They want an OD server, and AD server, and an XP box in the middle with the ADAM (AD Application Mode) tools installed so that we can connect to both directories and spit out the schema differences.  This was slightly annoying because I haven’t had an XP box around for….quite some time.  What I did was to use a Windows 2008 test server I had laying around, and added the AD LDS role.  LDS (Lightweight Directory Services) is the 2008 version of ADAM.  After installing that, the same diff tool was still available, so I didn’t need an XP box, and the instructions still worked flawlessly.

To save you some trouble, just grab the file here:  apple-mods.ldf

Obviously, be sure to test this in a TEST ENVIRONMENT first, because these changes aren’t as common as Microsoft provided schema updates, so who knows how they will affect your existing environment, especially if someone before you has already extended your schema with earlier Apple stuff.

Hat tip to Michael Kuron who has a blog post on an earlier schema update.  If you’re considering extending your schema, you’ll definitely want to read the comments at the bottom of that post.  Very informative.

-Robbie

Be Sociable, Share!

iPhone 4S Review

It’s been a while since I posted anything on this blog, and I’ve been thinking about getting things started again, so why not start with the iPhone 4S?  It’s not like there aren’t any reviews out there, but at least I can give you my take on it.

My last phone was the iPhone 3GS.  And before that, the original iPhone.  So yeah, i’ve been an iPhone guy for a while. Kinda surprising for a guy who used to not like Apple *at all*, but that was in the OS9 days.

I’ll admit to some disappointment regarding the 4S release.  I, like basically everyone else, expected a mind-blowing iPhone 5 with features that nobody would have been able to predict, but thats what happens when the rumor mill goes nuts.  Either way, the 3GS was old enough, and I was ready enough to upgrade (and switch from AT&T to Verizon), that I took the plunge, and got in line at the Apple store at ~4am on Friday morning.

So lets get to it.  The iPhone 4S has an amazing screen (the retina display), which is identical to the 4, but coming from a 3GS, it’s totally worth the upgrade just for that alone.  It’s definitely faster than prior models with the faster Apple A5 processor, but they clocked the processor at only 800MHz, which is slower than the identical processor in the iPad 2.  This was likely done to conserve battery life.  I’ve heard of some complaints about battery life in iOS 5 in general, but I have not experienced those problems.  In fact, the battery life has been great for me, except for the first few days when I was playing with it non-stop.

Siri:  Everybody is talking about Siri, and yes, it totally rocks.  Siri does say some crazy stuff but that has already been big news.  See “Shit that Siri Says“.  But how useful is it, really?  It’s way faster to get siri to do a few things than going through the usual apps and typing on the keyboard.  Just saying “Wake me up at 7am” sets the alarm.  Oh, you meant 6am?  Just say “make that 6am.”  Yeah, it’s that easy.  Also, typing text messages or email is way faster using Siri too, as long as you make a slight effort to speak clearly.  Even when you don’t talk that clear, it can usually still figure out what you meant.  That’s probably what I’ve been most impressed about after using other voice recognition products over the years.

Camera/Video:  The 8mp camera rocks.  The thing shoots full 1080p video at 30 frames per second.  60 fps would be ideal for motion (sports, etc), but I’ll settle for 30. :-)  It does very well in lower light conditions too.  There isn’t much need to haul around a point-and-shoot camera anymore, but I’ll probably still take my 12mp Sony DSX-WX5 on vacations.  Check out a test video I took on the 4S this past Friday at the NC State Fair below.  You’ll have to go to vimeo to see the full HD version:


2011 NC State Fair from Robbie Foust on Vimeo
So was it worth it?  For me, yeah, definitely.  But I love new techy geeky stuff, so for me it was a no-brainer.  If you already have an iPhone 4, they no, it’s probably not worth it, especially if you’re still in a contract.  Oh and by the way, yes, I get way better reception with Verizon at my house.

Feel free to ask questions and I’ll try to answer if I can.

-Robbie

 

Be Sociable, Share!

If you have a VMware ESX cluster running some Windows VMs, you’ve probably noticed very poor mouse response when on the console of your VMs. The fix is actually very simple. You need to bump up the hardware acceleration in the display preferences. You can either do it from the GUI (right click desktop -> properties -> settings -> advanced -> troubleshoot), or you can do it from Powershell:

set-itemproperty -path (((get-itemproperty "hklm:\hardware\devicemap\video")."\Device\Video0") -replace "\\Registry\\Machine","HKLM:") -name "Acceleration.Level" -value 0

What this command does is query the HKLM:\Hardware\Devicemap\Video registry branch to find the true location of your primary video device, and then sets the Acceleration.Level key to a value of 0.

The only problem with editing the registry setting directly is that Windows doesn’t automatically reload the display configuration, so the change doesn’t immediately take effect. Although it is technically possible to do that from Powershell, it isn’t easy (requires p/invoke) and you’re probably better off just rebooting the VM. :)

Be Sociable, Share!

Using Group Policy in Active Directory, you can force the Windows Firewall to be enabled across your servers or clients, but sometimes you might not want to do that.  After all, when troubleshooting a software communications problem, it’s really easy to rule out the firewall configuration as a possible problem if you can disable it for a few minutes while you troubleshoot.

The only problem with allowing that kind of flexibility is how do you know that you remembered to re-enable the firewall on those 30 servers you worked on last week?  Well, some quick googling will show that you can use WMI to query the HNet_ConnectionProperties class and look at the IsFirewalled property.  Except….it’s always True!  Even if the firewall is disabled.  Apparently, this is because the ICS service is running so the property is a bit misleading.

So I did things the hard way.  I used Regmon to find out what registry key was flipped on/off when I enabled/disabled the Windows Firewall, and wrote a quick Powershell function to query that setting and return True or False (as type [bool]).

# returns true if windows firewall is enabled, false if it is disabled
filter global:get-firewallstatus ([string]$computer = $env:computername)
	{
	if ($_) { $computer = $_ }
 
	$HKLM = 2147483650
 
	$reg = get-wmiobject -list -namespace root\default -computer $computer | where-object { $_.name -eq "StdRegProv" }
	$firewallEnabled = $reg.GetDwordValue($HKLM, "System\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile","EnableFirewall")
 
	[bool]($firewallEnabled.uValue)
	}

Update (Feb 1, 2009):

In the comments, Shay Levy reminded me of an alternate method of querying the registry that doesn’t use WMI. Here is the exact same script using the [Microsoft.Win32.RegistryKey] class. Thanks Shay!

filter global:get-firewallstatus2 ([string]$computer = $env:computername)
	{
	if ($_) { $computer = $_ }
 
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$computer)
 
	$firewallEnabled = $reg.OpenSubKey("System\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile").GetValue("EnableFirewall")
 
	[bool]$firewallEnabled
	}
Be Sociable, Share!

View/Download Get-Packet.ps1 Script

I’ve posted an updated version of my Get-Packet Powershell packet sniffer script.  It is still completely standalone (it doesn’t require any additional software to run).  New features include:

  • Added IP Version field
  • TCP flags are now stored in an array
  • New switch added to resolve IPs to hostnames
  • ESC key will cleanly exit the script
  • New switch added to generate statistics

.NET includes a method to resolve IPs to Hostnames in [System.Net.Dns]::GetHostByName(), but if the lookup fails, then there is a 5 second delay that forces the script to pause execution. I instead chose to scrape the output of nslookup since it returns much quicker.  To further decrease processing time, I cache the results in a hashtable so multiple calls to nslookup for the same host are not needed.

Using the -Statistics switch will cause the script to generate statistics after the ESC key is pressed to stop the trace.  Most of the statistics code was borrowed from Jeffery Hicks’s Analyze-Packet script.  A few basic stats will be printed to the screen with write-host, but the bulk of the data will be stored in a global $stats variable that you can access after the script has exited.  This isn’t how features would normally be implemented in cmdlets (they would be separate cmdlets), but I figured it would be ok in a script, and I have found the integration to be pretty convenient.

I had looked at adding IPv6 support, but design limitations in Windows prevented me from being able to access the raw IPv6 header.  See my earlier blog post for more details.  I also looked at adding the ability to save the capture in libpcap format, but I’m not getting the raw IP frame, so the data wouldn’t be as complete as a capture done in something like Wireshark.

Anyway, I hope you enjoy the new features!  Let me know in the comments if you would like to see any other features added.

  • EDIT: If you’re on Vista, you might need to disable the firewall to see TCP packets.  Not sure why yet. :)
  • EDIT #2: Found out why.  Add powershell.exe as an allowed application. (duh) :)

- Robbie

Be Sociable, Share!

View/Download get-regex.ps1 Script

When I write scripts, every now and then I need to use Regular Expressions.  RegEx’s are very powerful, but I don’t use them enough to have it all memorized.  So instead of searching for my quick reference book all the time, I just made a Powershell function to display all of the info at the prompt.

Poweshell’s built in “get-help” includes some basic RegEx documentation, but it is lacking some detail, and I don’t want to have to read through all the “fluff” to get to what I want.

The output of the script looks like this:

PS C:\scripts> get-regex | ft -auto
Sequence                    Meaning                                                                      Table
--------                    -------                                                                      -----
\a                          Alert (bell), x07.                                                           Character r...
\b                          Backspace, x08, supported only in character class.                           Character r...
\e                          ESC character, x1B.                                                          Character r...
\n                          Newline, x0A.                                                                Character r...
\r                          Carriage return, x0D.                                                        Character r...
\f                          Form feed, x0C.                                                              Character r...
\t                          Horizontal tab, x09.                                                         Character r...
\v                          Vertical tab, x0B.                                                           Character r...
\0octal                     Character specified by a two-digit octal code.                               Character r...
\xhex                       Character specified by a two-digit hexadecimal code.                         Character r...
\uhex                       Character specified by a four-digit hexadecimal code.                        Character r...
\cchar                      Named control character.                                                     Character r...
[...]                       A single character listed or contained within a listed range.                Character c...
[^...]                      A single character not listed and not contained within a listed range.       Character c...
.                           Any character, except a line terminator (unless single-line mode, s).        Character c...
\w                          Word character.                                                              Character c...
\W                          Non-word character.                                                          Character c...
\d                          Digit.                                                                       Character c...
\D                          Non-digit.                                                                   Character c...
\s                          Whitespace character.                                                        Character c...
\S                          Non-whitespace character.                                                    Character c...
 
(etc...)

Enjoy!

- Robbie

Be Sociable, Share!

 

IPv6 Ready Logo

About a year ago, I wrote a Powershell packet sniffer script that worked pretty well. I wanted to add IPv6 support to it, so I spent a good chunk of the last day learning the protocol and trying to figure out how to do it in Powershell/.NET. Unfortunately, what I found out is that it isn’t possible.

 

I basically had everything working, except for some reason I wasn’t receiving any IPv6 headers — only the payload. After lots of research (er..googling, and experimentation), I discovered that there is a design limitation in the Windows implementation of IPv6 that prevents incoming IPv6 headers from being passed to a raw socket. I also tried to get outgoing headers, but that wouldn’t work for me either. Without the header, it’s very difficult to figure out what protocol the payload is, so for now, I think I’m going to have to abandon this effort.

All is not lost though. I’ve made some other improvements to the original packet capture script and will post the new version soon.

- Robbie

Be Sociable, Share!

View/Download jiraFunctions.ps1 Script

Atlassian Jira is a web-based bug/issue tracking software, but lucky for us, they provide a WSDL interface so that we can access it from a Powershell command line.

This script is only successful because of the work of Lee Holmes’ connect-wsdl function.  I’ve included it as part of this script for convenience.

First you will need to edit the $jiraURL variable in the script so that it points to your Jira WSDL URL.  I usually initialize most of my functions (and some variables) globally to make things easier, so after you’ve made the necessary edit, just run it from a command line.  The script will prompt you for a login/password for Jira.

Note: Some functions are incomplete/untested, so be sure to test before using in a production environment!

Connect-Jira is the first function that is called, and it establishes an initial connection to the Jira webservice.  This is the function that uses Lee’s connect-webservice function (and I honestly don’t know enough C# to understand how it works).

$global:jira = connect-jira $jiraURL

After the connection is established, you are authenticated to Jira securely using a login/password.  Thanks to Joel Bennett for the clever bits of code to securely grab the password without storing it anywhere.  There is a session ID stored in the $jiraAuthID variable that is used to identify your session.  A valid $jiraAuthID must be passed to most functions for them to succeed.  If the ID has timed out, the function calls will fail.

$BSTR = [System.Runtime.InteropServices.marshal]::SecureStringToBSTR($credential.Password)
$global:jiraAuthID = $jira.login($credential.UserName.TrimStart("\"),[System.Runtime.InteropServices.marshal]::PtrToStringAuto($BSTR))
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR);

At this point, you are dropped back to the Powershell prompt where you can call the many functions available to you.  For example:

PS C:\scripts\jira> get-jiraserverinfo
 
baseUrl     : https://server.yourdomain.com/jira
buildDate   : 9/13/2006 4:00:00 AM
buildNumber : 161
edition     : Enterprise
version     : 3.6.5
PS C:\scripts\jira> get-jiraresolution
 
description                   icon                          name                          id
-----------                   ----                          ----                          --
A fix for this issue is ch...                               Fixed                         1
The problem described is a...                               Won't Fix                     2
The problem is a duplicate...                               Duplicate                     3
The problem is not complet...                               Incomplete                    4
All attempts at reproducin...                               Cannot Reproduce              5
The bug report describes b...                               NOTABUG                       6
Issue type was a general q...                               Issue Closed                  7
PS C:\scripts\jira> get-jiraissue "WIN-113"
 
affectsVersions   : {}
assignee          : rfoust
attachmentNames   : {}
components        : {}
created           : 7/11/2008 9:12:48 PM
customFieldValues : {}
description       : Create an altiris job to push out this script/command to all windows servers.  There's a bug in the
                     powershell installer so this doesn't get done.  When complete, powershell will start up *much* fas
                    ter.  In fact, thats almost an understatement. :)
 
                    Set-Alias ngen @(
                    dir (join-path ${env:\windir} "Microsoft.NET\Framework") ngen.exe -recurse |
                    sort -descending lastwritetime
                    )[0].fullName
                    [appdomain]::currentdomain.getassemblies() | %{ngen $_.location}
 
                    For more info, see:  http://blogs.msdn.com/powershell/archive/2007/11/08/update-gac-ps1.aspx
duedate           :
environment       :
fixVersions       : {}
key               : WIN-113
priority          : 4
project           : WIN
reporter          : rfoust
resolution        :
status            : 1
summary           : Update GAC on all servers to decrease powershell startup time
type              : 4
updated           : 7/23/2008 1:40:17 PM
votes             : 0
id                : 20685

Enjoy! :)

- Robbie

Be Sociable, Share!