Exchange 2010 and Lync 2010 PowerShell Syntax Highlighting File for UltraEdit

July 20th, 2011 No comments

If you write a lot of PowerShell code, you probably have a favorite text editor. Maybe you use Notepad, Notepad+, PowerShell ISE, etc. Mine is IDM Computer Solutions’ UltraEdit. I’ve been using UltraEdit for many years, including while doing web dev work. It’s feature packed and well worth the few dollars that it costs.

One of UltraEdit’s great features is the ability to do syntax highlighting, with support for many different languages. By default, UltraEdit doesn’t ship with a wordfile for PowerShell. There is a community that helps develop new syntax highlighting wordfiles, and lo and behold, someone created a PowerShell wordfile.

I’ve taken that file and added the Exchange 2010 and Lync 2010 cmdlets so that they are properly highlighted. The file can be downloaded from powershell.zip. Grab it and toss it into your %appdata%\IDMComp\UltraEdit\wordfiles folder. Enjoy!

Categories: PowerShell Tags:

Function: New-Share – Creating File Shares Via PowerShell

July 13th, 2011 4 comments

Description

Often we need to create file shares, and this is generally fairly boring. PowerShell can help streamline this process. This function will create the share, but does not set sharing permissions. We’ll cover that later.

This is based partly on How to Use PowerShell to create shared folders in Windows 7. I resolved some minor issues and added the pipeline parameters and some minor error checking, and the description. The script will create the folder if it doesn’t exist, and then share it.

function New-Share {
 param (
  [parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="No folder name specified")]
  [string]$FolderName,
    [parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="No share name specified")]
    [string]$ShareName,
    [parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$false, HelpMessage="No description specified")]
    [string]$Description
 )
 $error.clear()
 # Check for folder; Create it if it doesn't exist
 If (!(Test-Path $FolderName)) {
  New-Item $FolderName -type Directory | Out-Null
 }
 # Check for share; Create it if it doesn't exist
 $Shares=[WMICLASS]"WIN32_Share"
 if (!(Get-WMIObject Win32_share -filter "name='$ShareName'")){
  $Shares.Create($FolderName,$ShareName,0,65535,$Description) | Out-Null
  if (!($error)){
   # the share was created
   return $true
  } else {
   # there was an error
   return $false
  }
 } else {
  # the share already exists
  return $false
  }
} # end function New-Share

And we can then call the function with something like:

New-Share -FolderName "c:\LyncShare" -ShareName "LyncShare" -Description "Used by Lync server to store Address Book files, phone updates, and other important files."

As you can see, it’s pretty straight forward. We’ll cover setting both NTFS and Share permissions soon.

Donations

I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.

Categories: PowerShell Tags: ,

Function: Remove-ScriptVariables – Cleaning Up Script Variables in PowerShell

July 8th, 2011 3 comments

PowerShell-logo-128x84Description

When writing scripts that use variables, especially those that contain a fair amount of data, it’s best practice to clean up the environment when exiting. This frees up memory for other purposes, and allows you to leave the environment as clean as possible. This is accomplished using the Remove-Variable cmdlet.

As scripts become more complex and evolve over time, it can be tough to keep track of all variables in order to remove them at the end. I created this function to help deal with this. The function takes the path of the script file, inspects the file, compiles a list of variables in the script, and runs them through the Remove-Variable cmdlet. It builds on some of the code from Auto-Documenting Script Variables.

function Remove-ScriptVariables($path) { 
 $result = Get-Content $path | 
 ForEach { if ( $_ -match '(\$.*?)\s*=') {     
   $matches[1]  | ? { $_ -notlike '*.*' -and $_ -notmatch 'result' -and $_ -notmatch 'env:'}  
  } 
 } 
 ForEach ($v in ($result | Sort-Object | Get-Unique)){ 
  Write-Host "Removing" $v.replace("$","")
  Remove-Variable ($v.replace("$","")) -ErrorAction SilentlyContinue
 }
} # end function Get-ScriptVariables

We then call the function, passing the built-in $MyInvocation.MyCommand.Name value, which automatically contains the path and name of the currently running script. Essentially, we tell the function to run against it’s own script file:

Remove-ScriptVariables($MyInvocation.MyCommand.Name)

Donations

I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.

Categories: PowerShell Tags: ,

Changelog: Get-CsConnections.ps1

July 1st, 2011 8 comments

This is the changelog page for Get-CsConnections.ps1. You will find a complete list of released versions, their dates, and the features and issues addressed in each. Please refer to the script’s main page for more information including download links, installation details, and more.

v3.5 – 08-14-2019

  1. Added some cleanup for the VVX and Trio device agent strings. Thanks to @UcMadScientist. See https://www.ucmadscientist.com/quick-post-pat-richards-get-csconnections-and-polycom-devices/

v3.4 – 03-27-2018

  1. Added more bugs to fix later. 🙂
  2. Fixed -SkipUpdateCheck. Thanks to Mike for pointing it out.
  3. Fixed issue where preferred connection order would not display for Skype for Business users when using -SipAddress option
  4. Minor tweaks per PsScriptAnalyzer and PSSharper
  5. Updated Remove-Variable function to v1.2
  6. Get-UpdateInfo updated function to v1.5
  7. Set-ModuleStatus updated function to v1.6
  8. Write-Log updated function to v3.2

v3.3 – 01-04-2017

  1. Now requires at least PowerShell 3.0
  2. minor code cleanup
  3. updated Get-UpdateInfo to 1.1

v3.2 – 11-17-2016

  1. Added new update routine
  2. Signed with new certificate

v3.1 – 04-07-2016

  1. added -SkipUpdateCheck to skip update check

v3.0 – 09-09-2015

  1. clarified some examples in the help section
  2. added detection for Skype for Business Server 2015

v2.9 – 10-28-2014

  1. Fixed an issue where PowerShell v2.0 machines would choke on one line. Thanks to Thierry for pointing it out.
  2. New code-signing certificate to replace expired cert

v2.8 – 06-10-2014

  1. Clarified ShowTotal output per Nate’s comment
  2. Fixed an issue where LRS clients would show a leading space for the agent string
  3. changed FE server info to be lower case to that it’s consistent
  4. the -pool parameter is now -PoolFqdn to align with other scripts and cmdlets
  5. fine tuned some of the code used when specifying -SipAddress

v2.7 – 05-24-2014

  1. fixed check for updates dialog border
  2. defined OverallRecords as an array to avoid an issue. Thanks to Tristan for that info.
  3. fixed verbose output not showing server names. Thanks to Greig for pointing it out.

v2.6 – 02-08-2014

  1. tweaked the MaxEndpointsPerUser section to always use the global configuration. This only matters in environments where multiple configurations exist (Get-CsRegistrarConfiguration). Thanks to Matt for pointing this out.
  2. swaped in new version of Set-ModuleStatus function
  3. cleanup of param block per best practices
  4. cleanup of comment help per best practices
  5. swaped in new verion of Test-ScriptUpdates

v2.5 – 11-26-2013

  1. tweaked SQL query for case insensitivity per Jean-Luc
  2. comment help updated to include info on Windows firewall config
  3. tweaked code when getting info for a single user to fix missing data for pool connection order

v2.4 – 09-13-2013

  1. Fixed output for unique users/clients
  2. Now validates if UserHighConnectionFlag is specified, and does not exceed MaxEndPointsPerUser

v2.3 – 08-01-2013

  1. intro code for script update check
  2. better pool version detection. When using the -Pool option, you no longer need to specify -Is2013 if it’s a 2013 pool
  3. Added code to restart script in an elevated session if the current session isn’t elevated (previously the script just threw an error and exited)

v2.2 – 05-10-2013

  1. Added support for Lync Server 2013 by using the -Is2013 switch. If I can find a better way of automatically detecting the version, I’ll incorporate that in a later build.
  2. Some code optimization
  3. Bug fix for an issue where the names of servers in a pool wouldn’t display if the script was run in PowerShell v3.

v2.1 – 12-13-2012

  1. Minor formatting tweaks for better handling long client names, such as the Lync RT client.
  2. Minor bug fixes

v2.0 – 10.16.2012

  1. Added -IncludeHighUsers option. Similar to -IncludeUsers, but only shows those users who meet the UserHighConnectionFlag value (shown in white), or exceeds it (shown in red).
  2. Added -ShowTotal option. When finished, shows statistics for the org, including total number of Lync enabled users, the total number of voice enabled users, and the percentage of enabled users that are currently connected.
  3. Updated the code the assembles FQDNs when just a pool or server netbios name are specified.
  4. If -SipAddress option is used, additional information showing the preferred connection order for the user is now also included. This adds the functionality of one liners: Finding out which Lync pool servers a user is associated with, and the preferred connection order.

v1.9 – 09-21-2012

  1. Finally resolved the issue where some front end servers would have a different number for PrimaryRegistrarClusterId in SQL Express than others, causing some servers to not return data (and not throw an error). Special thanks to Dave Howe @ Microsoft for helping me identify a work around, and also to Bart, a SQL Engineer at a client site who helped me tweak the related SQL query.
  2. A little code optimization
  3. -Server option added that now allows you to target a specific server instead of an entire pool.
  4. This version is code signed. You no longer are required to have a PowerShell Execution Policy of unrestricted or RemoteSigned. However, the script cannot be edited at all, or the code signature breaks.
  5. -SipAddr now supports specifying just the left part of the SIP address, but only in organizations with ONE SIP domain. For example, -SipAddr bill.gates instead of -SipAddr bill.gates@microsoft.com.
  6. -Server supports specifying the netbios domain. The script will “guess” at the FQDN by using the domain name of the machine the script is running on and appending it to the netbios name.

v1.8 – 09-14-2012

  1. Tons of formatting changes, mostly subtle
    1. Server names in the pool list are sorted
    2. Server names in the ‘Frontend Server’ list are now sorted
    3. Connections are now sorted by client
  2. Added -ShowFullClient switch to show extended client info.
  3. If -pool is not specified, and only one registrar pool exists, the script will automatically use that pool.
  4. Some additional verbose output added for troubleshooting

v1.7 – 09-07-2012

  1. Minor display sorting cleanup
  2. Streamlined some code
  3. Removed -IncludeUsers from automatically being set when using -ClientVersion

v1.6 – 07-02-2012

  1. Added feature to show just specific client versions and the connected users with that client

v1.4 – 04-19-2012

  1. cleaned up some of the param() block and added some validation
  2. streamlined some of the code
  3. tweaked the displayed results a little to better handle longer agent strings

v1.3 – 12-27-2011

  1. tweaked the formatting a little to account for longer agent strings due to mobile clients
  2. ignore the RtcApplication-[guid] account when calculating users and displaying userlist
  3. added error if pool doesn’t have any servers
  4. added UserHighConnectionFlag in parameter block to support pipeline entry

v1.1 – 08-09-2011

  1. added comment based help
  2. added option to display user list
  3. updated formatting
  4. added code so it will run in a normal PowerShell session

v1.0 – 07-01-2011

  1. original version

Update Rollup 4 (UR4) for Exchange Server 2010 SP1 Released

June 22nd, 2011 No comments

UPDATE: This UR has been pulled from the Download Center due to problems with copying folders in Outlook. Please see Kevin Allison’s comments for more information.

Microsoft has released the following update rollup for Exchange Server 2010:

  • Update Rollup 4 for Exchange Server 2010 SP1 (2509910)

If you’re running Exchange Server 2010 SP1, you need to apply Update Rollup 4 for Exchange 2010 to address the issues listed below.

Remember, you only need to download the latest update for the version of Exchange that you’re running.

Here is a list of the fixes included in update rollup 4:

  1. 2537099 “80040154” error message when you try to configure external Client Access namespaces on an Exchange Server 2010 server
  2. 2536700 Outlook stops responding when you try to copy a folder to its subfolder by using Outlook in online mode in an Exchange Server 2010 SP1 environment
  3. 2536517 The Microsoft Exchange RPC Client Access service crashes intermittently on an Exchange Server 2010 server
  4. 2536494 It takes a long time to return results when you perform an Advanced Find search on a mailbox by using Outlook in online mode in an Exchange Server 2010 SP1 environment
  5. 2535648 The EMC takes a long time to open in an Exchange Server 2010 environment
  6. 2535130 Performance in Outlook or in OWA decreases when you use IMAP4 to access the contacts folder in an Exchange Server 2010 environment
  7. 2535105 There is no option to disable the Availability service in an Exchange Server 2010 environment
  8. 2533543 Event ID 2153 is logged on each database availability group member in an Exchange Server 2010 environment
  9. 2533538 You cannot look up the free/busy information of a user who is located on an Exchange Server 2010 organization from another Exchange Server 2010 organization
  10. 2533451 A RBAC role assignee can unexpectedly run the “Update-FileDistributionService” command on an Exchange Server 2010 server that is outside the role assignment scope
  11. 2519359 “Changes to the rule cannot be saved.” error message when you try to create a reply rule by using Outlook in an Exchange Server 2010 environment
  12. 2518850 You cannot receive email messages on a mobile phone by using ActiveSync in an Exchange Server 2010 environment
  13. 2517088 Public folder conflict resolution does not work as usual in an Exchange Server 2010 environment
  14. 2515259 “The items could not be copied.” error message when you run the Get-MailboxSearch cmdlet in an Exchange Server 2010 SP1 environment
  15. 2514709 Event ID 1001 after you successfully the install Exchange Server 2010 Unified Messaging server role
  16. 2514574 The Exchange RPC Client Access service crashes in an Exchange Server 2010 environment
  17. 2513723 The “New-MailboxImportRequest” cmdlet does not import all messages in a .pst file in the ANSI format in an Exchange Server 2010 environment
  18. 2512023 “GetUserOofSettings”, “SetUserOofSettings” and “GetUserAvailability” operations do not support Exchange Impersonation on the Exchange Server 2010 SP1 schema
  19. 2511897 You cannot send an email message to a mailbox for a brief period when you move the mailbox by using online move in an Exchange Server 2010 environment
  20. 2507463 You cannot move a mailbox that contains a corrupted Search Folder in an Exchange Server 2010 environment
  21. 2506820 The free/busy information does not display of a user whose mailbox is located on an Exchange Server 2003 server
  22. 2506049 The hierarchy of a new public folder database on an Exchange Server 2010 SP1 server is not replicated
  23. 2505968 The EdgeTransport.exe process crashes when you apply a rule that contains a bad email address in an Exchange Server 2010 environment
  24. 2504453 You cannot retrieve statistical information about a public folder by using the “Get-PublicFolderStatistics” cmdlet in an Exchange Server 2010 SP1 environment
  25. 2503337 Comments of your meeting response message is missing when you decline a meeting request in an Exchange Server 2010 environment
  26. 2501070 A RBAC role assignee can stop queue processing on an Exchange Server 2010 Hub Transport server or an Exchange Server 2010 Edge Transport server that is outside the role assignment scope
  27. 2500903 A space is missing in the subject line of a “Tentative” meeting response in an Exchange Server 2010 environment
  28. 2500648 “There are no items to show in this view.” error message when you try to view a folder in Outlook in an Exchange Server 2010 environment
  29. 2495167 You cannot recover a deleted public folder by using Outlook or MFCMAPI in an Exchange Server 2010 environment
  30. 2495010 The EdgeTransport.exe process consumes 100% CPU usage on an Exchange Server 2010 Edge Transport server or an Exchange Server 2007 Edge Transport server
  31. 2493393 You cannot use ECP to perform a wipe on a mobile phone in an Exchange Server 2010 SP1 environment
  32. 2492068 “The item cannot be saved to this folder.” error message when try to post an item to a mail-disabled public folder in an Exchange Server 2010 SP1 environment
  33. 2491354 You cannot view the free/busy information of users in a mixed Exchange Server 2007 and Exchange Server 2010 environment
  34. 2490134 A deferred delivery email message is not delivered by using Outlook 2007 in online mode in an Exchange Server 2010 environment
  35. 2489964 An update enables range 0x-0x1F characters in the display name of an Exchange Server 2010 user account
  36. 2489938 The “Connect-ExchangeServer” function does not change the target Exchange server in Exchange Server 2010
  37. 2489130 A RBAC role assignee can unexpectedly change mailbox properties that are outside the management role group scope in an Exchange Server 2010 environment
  38. 2488643 Outlook downloads duplicated POP3 email messages in an Exchange Server 2010 environment
  39. 2479188 The iCal parts of an email message contain invalid entries when they are sent from an Exchange Server 2003 mailbox to an Exchange Server 2010 mailbox
  40. 2477273 The DomainController parameter does not work when you use the “MoveMailbox.ps1” script to move mailboxes in an Exchange Server 2010 environment
  41. 2471964 A NDR is sent to the sender when you move an email message to a personal folder file in an Exchange Server 2010 SP1 or a later version environment
  42. 2467619 A user who manages a distribution group cannot remove another user whose mailbox is disabled in an Exchange Server 2010 environment
  43. 2465292 “MAPI_E_FAILONEPROVIDER (0x8004011D)” error message when you access an Exchange Server 2010 mailbox by using a MAPI application
  44. 2446908 ESE event descriptions are missing in Event Viewer when the Eseutil utility is called on an Exchange Server 2010 SP1 server
  45. 2394554 An email message is not delivered if it contains unsupported encoded characters in the subject line in an Exchange Server 2010 environment
  46. 2491951 You cannot install Exchange Server 2010 SP1 if the NetBIOS domain name of the domain controller contains an ampersand (&) character
  47. 2507066 Administrator audit logging is disabled unexpectedly during an Exchange Server 2010 SP1 installation

Download the rollup here.

Installation Notes:

If you haven’t installed Exchange Server yet, you can use the info at Quicker Exchange installs complete with service packs and rollups to save you some time.

Microsoft Update can’t detect rollups for Exchange 2010 servers that are members of a Database Availability Group (DAG). See the post Installing Exchange 2010 Rollups on DAG Servers for info, and a script, for installing update rollups.

Update Rollups should be applied to Internet facing Client Access Servers before being installed on non-Internet facing Client Access Servers.

If you’re installing the update rollup on Exchange servers that don’t have Internet access, see “Installing Exchange 2007 & 2010 rollups on servers that don’t have Internet access” for some additional steps.

Also, the installer and Add/Remove Programs text is only in English – even when being installed on non-English systems.

Note to Forefront users:

If you don’t disable Forefront before installing a rollup or service pack, and enable afterwards, you run the risk of Exchange related services not starting. You can disable Forefront by going to a command prompt and navigating to the Forefront directory and running FSCUtility /disable. To enable Forefront after installation of a UR or SP, run FSCUtility /enable.

Update Rollup 4 (UR4) for Exchange Server 2007 SP3 Released

June 22nd, 2011 No comments

Microsoft has released the following update rollup for Exchange Server 2007:

  • Update Rollup 4 for Exchange Server 2007 SP3 (2509911)

If you’re running Exchange Server 2007 SP3, you need to apply Update Rollup 4 for Exchange 2007 to address the issues listed below.

Remember, you only need to download the latest update for the version of Exchange that you’re running.

Here is a list of the fixes included in update rollup 4:

  1. 2531208 You cannot synchronize a folder hierarchy by using Outlook for Mac 2011 in an Exchange Server 2007 SP3 environment
  2. 2528437 EWS applications cannot connect to Exchange Server 2007 servers after you make changes on accepted domains
  3. 2521063 You are incorrectly displayed as a meeting organizer after you synchronize the meeting by using your mobile device in an Exchange Server 2007 environment
  4. 2517337 You cannot open a mailbox that has a “#” character in the primary SMTP email address by using OWA in an Exchange Server 2007 environment
  5. 2515428 The MSExchangeMailboxAssistants.exe process crashes when the managed folder assistant tries to journal a message in an Exchange Server 2007 environment
  6. 2508872 The W3WP.exe process in the Autodiscover application pool on the Exchange Server 2007 Client Access servers consumes excessive CPU resources
  7. 2507374 “Cannot open this item” error message in Outlook online mode in an Exchange Server 2007 environment
  8. 2506827 A UM auto attendant times out and generates an invalid extension number error message in an Exchange Server 2007 environment
  9. 2502276 A meeting request series are deleted unexpectedly from the calendar in an Exchange Server 2007 environment
  10. 2498924 “Could not connect to a directory server” error message when you click the last page button in the search results in Exchange Server 2007 OWA
  11. 2498156 OLM/OLD incorrectly runs against databases in a RSG in an Exchange Server 2007 environment
  12. 2496806 A mobile phone times out when you use ActiveSync to synchronize the calendar on the mobile phone with an Exchange Server 2007 mailbox
  13. 2543879 A PDF attachment sent from a Mac Mail client does not display when you open the email message by using Outlook 2010 in an Exchange Server 2007 SP3 environment
  14. 2491751 Spell checking does not function correctly in OWA when an S/MIME control is used and SSL Offloading is enabled in Exchange Server 2007
  15. 2484147 “HTTP Error 400 Bad Request” error message when you use OWA to log on to a newly created Exchange Server 2007 mailbox
  16. 2466220 Question mark (?) characters appear in the subject of a reply email message in an Exchange Server 2007 environment
  17. 2223294 A new feature is available to disable the “No end date” check box in OWA when you create a recurring meeting item in an Exchange Server 2007 environment
  18. 977906 You receive an error message when you run certain commands in the EMS on an Exchange Server 2007 server
  19. 2495010 The EdgeTransport.exe process consumes 100% CPU usage on an Exchange Server 2010 Edge Transport server or an Exchange Server 2007 Edge Transport server
  20. 2484817 A mailbox does not show in certain address lists after you run commands on an Exchange Server 2007 mailbox

Download the rollup here.

Installation Notes:

If you haven’t installed Exchange Server yet, you can use the info at Quicker Exchange installs complete with service packs and rollups to save you some time.

Microsoft Update can’t detect rollups for Exchange 2010 servers that are members of a Database Availability Group (DAG). See the post Installing Exchange 2010 Rollups on DAG Servers for info, and a script, for installing update rollups.

Update Rollups should be applied to Internet facing Client Access Servers before being installed on non-Internet facing Client Access Servers.

If you’re installing the update rollup on Exchange servers that don’t have Internet access, see “Installing Exchange 2007 & 2010 rollups on servers that don’t have Internet access” for some additional steps.

Also, the installer and Add/Remove Programs text is only in English – even when being installed on non-English systems.

Note to Forefront users:

If you don’t disable Forefront before installing a rollup or service pack, and enable afterwards, you run the risk of Exchange related services not starting. You can disable Forefront by going to a command prompt and navigating to the Forefront directory and running FSCUtility /disable. To enable Forefront after installation of a UR or SP, run FSCUtility /enable.

Script: Set-WindowsEmailAddress.ps1 – Set WindowsEmailAddress Field for Users in a Non-Exchange Environment

June 12th, 2011 No comments

Windows-logo-128x128A friend of mine had a dilemma. Her environment doesn’t have Exchange, but does has some LDAP apps that query AD. They needed to set the WindowsEmailAddress field on all AD user accounts to first.last@domain.com. In Exchange, this is automatically set when a user is mail or mailbox enabled. No such luck here (and not for a lack of me trying!). And, since there are hundreds and hundreds of users, manually setting each user was a task best left for those with no life. So – PowerShell to the rescue.

In the ActiveDirectory module, available on Domain Controllers, we have both Get-AdUser and Set-AdUser. These are really the only two cmdlets we need to fill the requirement. We essentially use Get-AdUser to get all of the users in a specific OU:

[object] $objUsers = Get-AdUser -filter * -ResultSetSize $null | Where-Object {$_.DistinguishedName -match $ou -and $_.GivenName -ne $null -and $_.Surname -ne $null}

$ou is defined as the target OU containing all users we want to process. The script will include all children OUs as well. Not in this OU are service accounts and non email enabled accounts. So we have an array with users. We’re 1/2 way there. We then cycle through the array using a ForEach and set the email address by combining the first name, a “.”, the second name, an “@”, and the SMTP domain. But I wanted to do some simple cleanup of the addresses. First concern was people with multiple names in either the first name or last name fields. Think “Billy Ray”.  This was simple enough using a simple replace:

$strEmail = ($objUser.GivenName).replace(" ","") + "." + ($objUser.Surname).replace(" ","") + "@" + $SMTPDomainName

The second concern was consistent formatting of case. I’m a big believer that Capitalizing each word in an email or URL address (aka “CamelCase”) makes them easier to read quickly. Doing some digging around, I found Get-Culture.TextInfo.ToTitleCase. This will capitalize each word, so “billy ray cyrus” becomes “Billy Ray Cyrus”. Unfortunately, “BILLY RAY CYRUS” stays the same. A little ToLower() magic and poof – perfection:

$strEmail = ((Get-Culture).TextInfo.ToTitleCase($objUser.GivenName.ToLower()).replace(" ","")) + "." + ((Get-Culture).TextInfo.ToTitleCase($objUser.Surname.ToLower()).replace(" ","")) + "@" + $strSMTPDomainName

So we’ve got the users, and we’ve figured out how to create the email address. Lastly, we actually make the change. Within our loop, we simply run

Set-AdUser $objUser.SamAccountName -emailaddress $strEmail

Results in just a few lines!

Now, my friend hasn’t embraced the PowerShell way of life yet, so I figured I’d spruce things up a little. Rather than have to manually type the OU path, I found a post that showed how to create a GUI based OU picker. It got me about 3/4 the way there, and added ~100 lines to the script. I added the “OK” button and dumped the results back into the script. I added a prompt for the SMTP domain name as well. The script now adds a transcript for a record of what was done and some code to ensure the ActiveDirectory module is available and loaded (just in case the script is run from a normal PowerShell session and not the Active Directory Module for Windows PowerShell session).

I didn’t really add any error checking, as this is a one-off script meant to just save a little time.

if this is the first script you’re running, then

.\Set-WindowsEmailAddress.ps1 -SMTPDomainName [SMTP domain]

to execute the script. Follow the prompts. Pretty simple stuff.

Installation

Execution Policy: Third-party PowerShell scripts may require that the PowerShell Execution Policy be set to either AllSigned, RemoteSigned, or Unrestricted. The default is Restricted, which prevents scripts – even code signed scripts – from running. For more information about setting your Execution Policy, see Using the Set-ExecutionPolicy Cmdlet.

Donations

I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.

Download

v1.2 – 01-27-2014 Set-WindowsEmailAddress.v1.2.zip

v1.1 – 10-01-2011 Set-WindowsEmailAddress.v1.1.zip

v1.0 – 06-12-2011 Set-WindowsEmailAddress.zip

Changelog

See the changelog for this script which details all versions and their features.

Categories: PowerShell Tags: ,

Changelog: Set-WindowsEmailAddress.ps1

June 12th, 2011 No comments

This is the changelog page for Set-WindowsEmailAddress.ps1. You will find a complete list of released versions, their dates, and the features and issues addressed in each. Please refer to the script’s main page for more information including download links, installation details, and more.

v1.2 – 01-27-2014

  1. Updated Set-ModuleStatus function
  2. cmdlet binding
  3. testing for ISE to avoid errors with Start-Transcript

v1.1 – 10-1-2011

  1. code cleanup
  2. variable cleanup
  3. replaced some code with my normal functions
  4. expanded comment based help
  5. account for zero results

v1.0 – 06-12-2011

  1. Original version

All Lync 2010 Cmdlets and the Default RBAC Roles That Can Use Them

June 1st, 2011 No comments

A customer asked for some documentation as to the various Lync cmdlets, what they do, and who can do them. Knowing that there are hundreds of cmdlets for Lync, this was a daunting task. Thank goodness for PowerShell, copy & paste, and some macros!

I used the script by Cezar Ungureanasu at http://blogs.technet.com/b/csps/archive/2010/06/10/scriptlistrbacrolesandcmdlets.aspx which shows you how to find out what cmdlets are available to specific default RBAC roles. I ran that in a virgin environment and captured the data to a .tsv file. I found a page from Microsoft at http://blogs.technet.com/b/csps/archive/2010/07/16/refallcmdlets.aspx which includes all 546 of the Lync cmdlets, a link to their associated Technet page, and a brief description. I merged that data into the .tsv file, and then added a formula that can be used to confirm what RBAC roles each cmdlet can be used by (in case an environment has been changed from the default settings). All of that was rolled into an Excel spreadsheet that can now be downloaded at the link below. This was perfect for the customer.

Recent updates include cmdlets added in Cumulative Update 4, as well as a new column indicating when the cmdlets were added to Lync. I’ll update that as I get more information.

Let me know if there are any issues, or if you can think of something I should add.

Download

v1.1 DefaultCmdletsByRBACRolev1.1.zip (11-20-2011)

v1.0 DefaultCmdletsByRBACRole.zip (06-01-2011)

[Redirect] Automated Prerequisite Installation via PowerShell for Lync Server 2010 on Windows Server 2008 R2

April 27th, 2011 No comments

Update: A newer version of this script has been released, and is available at Set-Lync2010Features.ps1 v5.0 – automated prereq PowerShell script for Lync Server 2010 released

If you’ve followed this blog for a while, you may remember one of the more popular posts, Automated prerequisite installation via PowerShell for Exchange Server 2010 on Windows Server 2008 R2. In that script, I used some simple techniques to help take some of the boring tasks out of installing Exchange 2010 servers. It was updated several times, and a new update is coming soon.

Well, Lync Server MVP Stale Hansen took that script and adapted it to installing the prerequisites for Lync Server 2010 and posted the results online. He did some neat things like installing the Best Practice Analyzer and the Resource Kit.

I got tasked with Lync responsibilities on my current project, so I took a closer look at the Stale’s version of the script, and decided to add some more code. Here are some of the changes:

  1. The script now prompts you about installing the telnet client. The telnet client isn’t REQUIRED, but is often recommended. Since my current project is in a high security environment, installing anything that isn’t absolutely required is generally frowned upon. So I made it optional.
  2. I added the option to disable IPv6. Lync Server 2010 doesn’t make use of IPv6 at all, so this option might prove handy.
  3. I added the option to install the Lync Server 2010 Stress and Performance Tool, the Visual C++ 2008 Redistributable that the Lync installer complains about, and options to install the recently released IM and Expert feature as well as starting Windows Update. Note that the IM an Expert piece is still early in testing. Note also that the Visual C++ install should be done after rebooting the server, otherwise it throws errors.
  4. Behind the scenes, I cleaned up a LOT of code – something I’ve been meaning to do to the Exchange prereq script as well. The script now looks to see if something is installed before trying to install it. The Resource Kit and BPA both have documentation that is MS Word based, so the script will ask you if you want to automatically install the free MS Word viewer and related filters.
  5. The OS detection method was cleaned up, and now supports any version of 2008 R2, including RTM and various service packs.

I’ve built 6 production servers and haven’t noticed any issues yet. But, as always, use at your own risk.

The code can be downloaded at Set-Lync2010Windows2008R2Features.zip. Rights required are local server admin. Also, set your execution policy to unrestricted in order to be able to run this unsigned script.

I welcome any comments, suggestions, concerns.