TheGeekery

The Usual Tech Ramblings

Raspberry Pi and the dreaded undervoltage notifications

I’ve been tinkering around a bit with some Raspberry Pi devices for a number of little projects. Most have been related to home automation type stuffs, but I built one with a 7” screen that I was going to be using for radio related things. Originally I had tossed together a small kit with an SDR for use on a camp because I knew we’d be out of range of cell phone service, but knew I could still take advantage of radio frequencies from satellites to get data, specifically weather images.

All seemed to go quite nicely, however I’d sporadically get a lightening bolt in the top right corner of the screen. I later learned that was a sign that the Pi wasn’t getting enough voltage. This baffled me, I was using a decent 5v power source, why would I get a low voltage issue? So I decided to do some research.

Powershell and Single vs Double Quotes

There can be a lot of confusion over when to use single and double quotes in PowerShell. Not to worry, this confusion carries over in a lot of programming and scripting languages, such as Perl. I figured, after seeing this tweet, to give a quick run down of when to use which one.

Powershell and Progress Feedback

We’re in the process of enabling a new password reset portal, which requires additional licensing features in Office 365. There is no “apply all” button in Office 365, so we have to do this via script to tens of thousands of user accounts. The problem with this is some form of feedback to the user running the script. PowerShell has some really handy built in features, such as a progress bar. It’s amazing how something so simple can make you feel a little better, and actively see how things are moving along. Progress bars in PowerShell are incredibly simple.

Custom Windows installs, injecting drivers and features

One of the things about new platforms is you get to learn new technology. One of the bad things about new technology is that a lot of your old methods might not apply anymore, need to be revamped, or redesigned completely. Over the last few months I’ve been working on a Cisco UCS platform deployment for work. This has been quite exciting as it’s all new gear, and it’s implementing stuff that we should have been able to implement with our HP BladeSystem C7000 gear.

vSphere Storage vMotion times out at 32% when crossing SANs

A year or so ago we’d upgraded our vCenter from 4.1 to 5.1, and with this upgrade, and some features built into our SAN, we got access VAAI. For example, removing a VM guest would tell the SAN that the guest had been removed, and if the data store had been thinly provisioned from the SAN, it’d clean up and shrink down the space used (in theory).

Another feature we discovered was something called “fast copy”. In layman’s understanding of this feature, when a storage vMotion request was created, the SAN was notified of the request, and the SAN would process the copying of the bits in the background. This is handy because it stops the data from being sent from SAN to host to SAN again. This causes a good speed up with regards to moving machines around.

Enable-RemoteMailbox - The address is invalid

In the process of migrating our mailboxes from our on-premise Exchange servers to Office 365, we had to rewrite the mailbox enable scripts. This script keys off of our HR database, does some magic, then calls Enable-Mailbox on Exchange 2010 servers. To update this to support creating mailboxes in Office 365, we needed to set user licenses, and use the Enable-RemoteMailbox command in Exchange 20131.

One of the quirks we stumbled upon is a bug in the Exchange 2013 tools that didn’t allow it to identify the domain for the remote routing address. This is what we’d get:

[PS] C:\ > Enable-RemoteMailbox Jonathan.Angliss

The address '@mytenant.mail.onmicrosoft.com' is invalid: "@mytenant.mail.onmicrosoft.com" isn't a valid SMTP address. The domain name can't contain spaces and it has to have a prefix and a suffix, such as example.com.
    + CategoryInfo          : NotSpecified: (:) [Enable-RemoteMailbox], DataValidationException
    + FullyQualifiedErrorId : [Server=Exchsvr01,RequestId=190c9764-d8bd-446e-ac43-7c80bcc54eea,TimeStamp=6/3/2014 1:19:33 PM] [FailureCategory=Cmdlet-DataValidationException] 730D5E7F,Microsoft.Exchange.Management.RecipientTasks.EnableRemoteMailbox
    + PSComputerName        : Exchsvr01


According to the Microsoft documentation for Enable-RemoteMailbox you should be able to specify just the sAMAccountName as an argument, the rest should be calculated.

The remote routing address doesn’t need to be specified because mail flow between the on-premises organization and the service has been configured. Using this configuration, the Enable-RemoteMailbox cmdlet automatically calculates the SMTP address of the mailbox to be used with the RemoteRoutingAddress parameter. — Microsoft TechNet

This apparently isn’t the case, so some tweaking was needed. We called upon Get-ADUser to retreive the account, and fill in the rest.

[PS] C:\ > Get-ADUser jonathan.angliss | Enable-RemoteMailbox $_.sAMAccountName -RemoteRoutingAddress "$($_.sAMAccountName)@mytenant.mail.onmicrosoft.com"

As this is part of a script, the content is slightly different, but you can see how it works. We used Get-ADUser earlier in the script to pull other user data to calculate licensing requirements, but if you’re doing this as a one off and are seeing the error then you could just as easily do this:

[PS] C:\ > Enable-RemoteMailbox jonathan.angliss -RemoteRoutingAddress 'jonathan.angliss@mytenant.mail.onmicrosoft.com'

Hat tip goes to Steve Goodman for posting similar work, and getting me back on track.

  1. If you are using a 2010 Exchange environment, you need a 2013 server to act as a Hybrid server to migrate users. 

Exchange 2010, 2013, and Office365: Dynamic Distribution List Filters

In our transition to using Offce365 for email services, we’ve had some interesting discoveries. Some of them are revolving around Dynamic Distribution Lists (DDLs). These are groups which have members identified at time of delivery of emails, and are based on various styles of queries. We usually use PowerShell style queries to build the groups, but LDAP works, as does simple queries based on fixed parameters.

One of the interesting observations is that Exchange will tack extra query parameters into the DDL to exclude system mailboxes. For example the following query string:

(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')

Will actually result in the follow query:

((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')) -and (-not(Name -like 'System{*')) 
-and (-not(Name -like 'CAS_{*')) -and )-not(-not(RecintTypeDetailsValue -eq 'MailboxPlan')) 
-and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox')) 
-and (-not(RecipientTypeDetailsValue -eq 'ArbitrationMailbox')))

This forces Exchange to exclude any of the system mailboxes for delivery, which is what you want it to do. The problem is, this additional data varies from version to version, and it’s not always backwards compatible. One of the observations is that in Exchange 2013 they introduced a RecipientTypeDetailsValue of PublicFolderMailbox. This is great, except that value is invalid in 2010. What does that mean?

Let’s try an example. From one of our on-prem 2013 hyrbid servers, we’re going to create a new distribution group with the initial query we gave as an example above…

New-DynamicDistributionGroup -Name 'JATestDist' -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')"

Now it’s created, lets see what we have for a query parameter:

PS C:\> Get-DynamicDistributionGroup -Identity 'JATestDist' | Select RecipientFilter | fl


RecipientFilter : ((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano'))) -and (-not(Name -like
                  'SystemMailbox{*')) -and (-not(Name -like 'CAS_{*')) -and (-not(RecipientTypeDetailsValue -eq
                  'MailboxPlan')) -and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox')) -and
                  (-not(RecipientTypeDetailsValue -eq 'PublicFolderMailbox')) -and (-not(RecipientTypeDetailsValue -eq
                  'ArbitrationMailbox')))

As we can see, a whole bunch of extra options, including our PublicFolderMailbox option. Lets test to see what users we get back…

[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter

Name                                                        RecipientType
----                                                        -------------
Angliss, Jon                                                UserMailbox

Okay, so we get results back, no big deal right? Now I’m going to go to a 2010 server, and without changing anything, I’m going to see what results we get back…

[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
The recipient preview filter string "((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano'))) -and (-not(Name -like 'SystemMailbox{*')) -and (-not(Name -like 'CAS_{*')) -and (-not(RecipientTypeDetailsValue -eq 'MailboxPlan')) -and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox')) -and (-not(RecipientTypeDetailsValue -eq 'PublicFolderMailbox')) -and (-not(RecipientTypeDetailsValue -eq 'ArbitrationMailbox')))" is neither a valid OPath filter nor a valid LDAP filter. Use the -RecipientPreviewFilter parameter with either a valid OPath filter string or a valid LDAP filter string.
    + CategoryInfo          : InvalidArgument: (:) [Get-Recipient], ArgumentException
    + FullyQualifiedErrorId : 79B22B5B,Microsoft.Exchange.Management.RecipientTasks.GetRecipient

Now we see an error. This is because 2010 doesn’t like PublicFolderMailbox as a RecipientTypeDetailsValue, and as such, throws it out as an error. So we have to go back to the 2010 server and edit the query, and reset it to be what we wanted originally:

[PS] C:\>Set-DynamicDistributionGroup -Identity 'JATestDist' -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')"
[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter

Name                                                        RecipientType
----                                                        -------------
Angliss, Jon                                                UserMailbox

This same query is happy on the 2013 servers as well, however, it will attempt delivery to a Public Mailbox if your other query parameters allow for it. In the example above, we set the RecipientType to be a very specific value, so this shouldn’t allow for this to happen anyway.

One other observation, when migrating your queries to be Office 365 Hybrid complaint, you will also need to include the RecipientType of MailUser. For example:

((RecipientType -eq 'UserMailbox') -or (RecipientType -eq 'MailUser')) -and (CustomAttribute4 -eq 'Plano')

Mailboxes that are migrated change their RecipientType to be MailUser.

There are lots of other fun things about DDLs that you’ll have to be aware of, which I shall cover in a separate post, but this is one of the fun gotchas I discovered in a mixed environment that’ll impact people using Exchange 2010 and 2013 in the same environment.

Exchange and The Case of The Missing Counters

While setting up SolarWinds SAM AppInsight for Exchange, I stumbled across a small Exchange setup bug where it’s not correctly deploying all the counters for the server roles that are being used. When SAM does the checks for the performance counter, you’ll see an error like the following:

'Average Document Indexing Time'
'Performance counter not found'

The solution is fairly simple, you have to copy the counters from the install media, and register them using PowerShell. The one caveat is that the counters aren’t on all the install media, so if you have CU3 setup files for example, they are not there. You have to go back to the original install DVD and get them from there. Here are the steps:

  1. Find the missing performance counter files on the install media, usually in <install media>\setup\perf
  2. For the above counter, the files needed are:
    1. IndexAgentPerfCounters.h
    2. IndexAgentPerfCounters.ini
    3. IndexAgentPerfCounters.xml
  3. Copy the files to <install path>\Setup\perf
  4. Open a PowerShell prompt with elevated privileges
  5. Execute the following commands:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Setup
New-PerfCounters -DefinitionFileName "<install path>\Setup\Perf\IndexAgentPerfCounters.xml"

Obviously adjust <install path> to be the correct path.

This is documented on the SAM product blog (here) and in the SolarWinds Knowledge Base (here), with the missing step of Add-PSSnapin.