Monday, September 16, 2013

Copy attribute from one field to another with PowerShell

This week, while prepping two different customers for single-signon to Office 365, I ran into the same issue--the userPrincipalName attribute was correctly populated (, but the email address was blank.  So, to rectify this problem, I put together a script that reads the UPN attribute and then copies to the the mail attribute.

Leave me a comment if you find it useful!

# Populate "mail" attribute with UPN
Import-Module ActiveDirectory

Get-ADUser -LDAPFilter '(userPrincipalName=*)' `
-Properties userPrincipalName,mail | Select-Object * | `
ForEach-Object { Set-ADObject -Identity `
$_.DistinguishedName -Replace `
@{mail=$($_.userPrincipalName)} }

Tuesday, August 6, 2013

Managing via WinRM

What is WinRM?

WinRM, for those of you not in the know, is really the Microsoft answer to an age-old problem in the Windows world--remote command and task execution.  It's the Windows equivalent of the Unix rsh, a native implementation of the PsExec (albeit, with the added complexity that seeps into nearly all Microsoft technologes).  It's built on SOAP, so it's intended to be firewall-friendly.

The quick guide to enabling it:

On a server you wish to enable WinRM managment, open an elevated command or PowerShell prompt and run winrm quickconfig.  Answer "Yes" to create the listener and open the necessary ports in the Windows Firewall.

Once that's done, you may need to set the configuration to allow you to connect to it and issue remote commands.  You can do this by by opening an elevated command or PowerShell prompt and entering one of the following command examples:

Add a single trusted remote management host

winrm set winrm/config/client '@{TrustedHosts="server1"}'

Add multiple trusted remote management hosts

winrm set winrm/config/client '@{TrustedHosts="server1,server2"}'

Make every host trusted (not advised)

winrm set winrm/config/client '@{TrustedHosts="*"}'

Now What?

Let's say you want to execute a command against a WinRM host.  To do this, use the command winrs.

For example, to open a command prompt on server2, you would run:

winrs -r:server2 cmd

For a whole bunch of other stuff you can do with WinRM, please see the following (much more technical) articles:

Happy remoting!

Tuesday, April 23, 2013

Handy Office 365 PowerShell Cmdlets

Here are some handy Cmdlets that you may find useful when managing Office 365.

- Connect to the Microsoft Online Services interface for account management tasks.
import-module MSOnline
$cred = Get-Credential
Connect-MSOLService -credential $cred

- Connect to the Microsoft Exchange Online interface for Exchange-related tasks.
$cred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session

- Set Office 365 passwords for all accounts to P@ssword1 and clear Change Password Flag (not valid for ADFS customers)
Get-MsolUser | Set-MsolUser -NewPassword P@ssword1 -ForceChangePassword $False

- Set Office 365 passwords for all accounts to never expire (not valid for ADFS customers)
Get-MsolUser | Set-MsolUser -PasswordNeverExpires $True

- Set Time Zone to Eastern Time and Language to English (US) for all users
get-mailbox -Filter {RecipientTypeDetails -eq 'UserMailbox'} | Set-MailboxRegionalConfiguration -Language "en-US" -TimeZone "Eastern Standard Time" -DateFormat "M/d/yyyy" -TimeFormat "h:mm tt"

- Get a user's mailbox permissions on a selected mailbox
Get-MailboxPermission -Identity <> | Where {_.User -like '*user*'}
Get-RecipeintPermission -Identity <> | Where {_.Trustee -like '*user*'}

- Get a list of Directly-granted rights, excluding "SELF"
Get-Mailbox | Get-MailboxPermission | Where-Object { ($_.AccessRights -like '*full*') -and ($_.IsInherited -eq $false) -and -not ($_.User -like '*nt authority\self*') }
Get-Mailbox | Get-RecipientPermission | Where-Object { ($_.AccessRights -like '*send*') -and ($_.IsInherited -eq $false) -and -not ($_.User -like '*nt authority\self*') }

- Set Shared Mailbox quota at 4.5GB
Get-Mailbox -RecipientTypeDetails SharedMailbox | Set-Mailbox -ProhibitSendQuota 4500MB -ProhibitSendReceiveQuota 5000mb -IssueWarningQuota 4400mb

- Get Distribution Group Members
$Groups| foreach {
 $Report=Get-distributionGroupMember -identity $_.identity| select @{Name='Distribution Group'; Expression={[String]::join(";", $GroupName)}}, DisplayName, PrimarySmtpAddress
$Reports | Export-csv -NoType -Path .\"output.csv" -ErrorAction SilentlyContinue

- Add Alias Domain to All Mailboxes (not valid for ADFS customers)
$users = Get-Mailbox
$aliasdomain =
foreach ($a in $users) {$a.emailaddresses.Add("$($a.alias)@$aliasdomain")}
$users | %{Set-Mailbox $_.Identity -EmailAddresses $_.EmailAddresses}

- Set Usage Location to United States for All users
Get-MsolUser | Set-MsolUser -UsageLocation "US"

- Assign "Exchange Online Plan 1" License to All Users for organization TestOrg
Get-MsolUser | Set-MsolUserLicense -addlicenses "testorg:EXCHANGESTANDARD"

- Force Removal of deleted mailboxes from Recycle Bin
Get-MsolUser -ReturnDeletedUsers | Remove-MsolUser -RemoveFromRecycleBin -Force

- Get All User Mailbox Sizes
Get-Mailbox -Resultsize Unlimited | Get-MailboxStatistics | Select-Object DisplayName,TotalItemSize

- Convert User mailbox to Room Mailbox
Set-Mailbox -Identity ConferenceRoom -Type Room

Set-MailboxFolderPermission -Identity ConferenceRoom:\Calendar -user Default -AccessRights Author
Let me know if there are other tasks you might like to see demonstrated!

Thursday, April 11, 2013

Cannot create Exchange Online Migration Endpoint with Exchange 2007 Server using only NTLM Authentication

I've been battling an issue for a few days now and finally stumbled upon a workable solution via PowerShell.


Client has an existing Exchange 2007 deployment.  The OWA instance is configured to only use NTLM authentication.  ExRCA ( comes back clean, and I can proxy log in to any mailbox on the server.

When configuring the migration endpoint through the EAC, I would receive an error that the migration endpoint could not be discovered, even after entering the credentials, server, and RPC proxy server values manually.


The solution ended up with my old friend PowerShell.  You can create migration endpoints through it using the New-MigrationEndpoint cmdlet.  The key was forcing the authentication to NTLM.

New-MigrationEndpoint -ExchangeOutlookAnywhere -Name NewEndPointName -ExchangeServer EXCHSERVER.DOMAIN.local -RpcProxyServer -Credentials (get-credential -EmailAddress -SkipVerification -Authentication NTLM