Archive

Posts Tagged ‘PowerShell’

Function: Get-PstFiles – List All .pst Files In A Given Path, With Name, Path, Size, and Owner

May 13, 2013 1 comment

Description

If you need to make a list of the .pst files in a given path, this function should help. It will get all .pst files, their name, path, size (in MB), and owner. This should help if you’re looking at importing the files in Exchange Server. If you’d like to export the results to a file, use the -file switch, with a filename, and the function will save the info to a .csv file.

Syntax

Get-PstFiles [[-path] ] [[-filter] ] [[-file] ] [-WhatIf] [-Confirm] []

Download

v1.1 – 05-13-2013 Get-PstFiles.v1.1.zip

Syntax Highlighting File for UltraEdit Includes Exchange 2010/2013, Lync 2010/2013, and ActiveDirectory cmdlets

In a previous post, Exchange 2010 and Lync 2010 PowerShell syntax highlighting file for UltraEdit, I included the cmdlets for both Exchange 2010 and Lync 2010. In this new file, I’ve included Lync 2010, Lync 2013, Exchange 2010, Exchange 2013, and Active Directory cmdlets for highlighting. If you use UltraEdit, this wordfile may make life a little easier.

Download the file here:

Function: Set-TimeZone – Configure Time Zone via PowerShell

March 4, 2013 1 comment

It’s easy to just double-click on the time in the system tray and set the time and time zone when building a new server. You may even have a GPO that does this for you. That’s all fine and dandy. But GPOs don’t work for member servers, and if you build a lot of servers, like I do, it’s a repetitive task – something perfectly suited for PowerShell.

With this function, we do nothing more than call tzutil.exe with the timezone name. Nothing fancy. I added some validation to make sure that the timezone specified is truly one of the 100 valid time zones that tzutile.exe should recognize and accept.

So, now, in your server provisioning script, merely call the function, Set-TimeZone, with the desired timezone. For example:

Set-TimeZone "Pacific Standard Time"

The script defaults to “Eastern Standard Time” if you don’t supply a timezone. That’s it. There is no screen output for this function. Here’s the function:

function Set-TimeZone {
  [CmdletBinding(SupportsShouldProcess = $True)]
  param( 
    [Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, Mandatory = $False)]
    [ValidateSet("Dateline Standard Time","UTC-11","Hawaiian Standard Time","Alaskan Standard Time","Pacific Standard Time (Mexico)","Pacific Standard Time","US Mountain Standard Time","Mountain Standard Time (Mexico)","Mountain Standard Time","Central America Standard Time","Central Standard Time","Central Standard Time (Mexico)","Canada Central Standard Time","SA Pacific Standard Time","Eastern Standard Time","US Eastern Standard Time","Venezuela Standard Time","Paraguay Standard Time","Atlantic Standard Time","Central Brazilian Standard Time","SA Western Standard Time","Pacific SA Standard Time","Newfoundland Standard Time","E. South America Standard Time","Argentina Standard Time","SA Eastern Standard Time","Greenland Standard Time","Montevideo Standard Time","Bahia Standard Time","UTC-02","Mid-Atlantic Standard Time","Azores Standard Time","Cape Verde Standard Time","Morocco Standard Time","UTC","GMT Standard Time","Greenwich Standard Time","W. Europe Standard Time","Central Europe Standard Time","Romance Standard Time","Central European Standard Time","W. Central Africa Standard Time","Namibia Standard Time","Jordan Standard Time","GTB Standard Time","Middle East Standard Time","Egypt Standard Time","Syria Standard Time","E. Europe Standard Time","South Africa Standard Time","FLE Standard Time","Turkey Standard Time","Israel Standard Time","Arabic Standard Time","Kaliningrad Standard Time","Arab Standard Time","E. Africa Standard Time","Iran Standard Time","Arabian Standard Time","Azerbaijan Standard Time","Russian Standard Time","Mauritius Standard Time","Georgian Standard Time","Caucasus Standard Time","Afghanistan Standard Time","Pakistan Standard Time","West Asia Standard Time","India Standard Time","Sri Lanka Standard Time","Nepal Standard Time","Central Asia Standard Time","Bangladesh Standard Time","Ekaterinburg Standard Time","Myanmar Standard Time","SE Asia Standard Time","N. Central Asia Standard Time","China Standard Time","North Asia Standard Time","Singapore Standard Time","W. Australia Standard Time","Taipei Standard Time","Ulaanbaatar Standard Time","North Asia East Standard Time","Tokyo Standard Time","Korea Standard Time","Cen. Australia Standard Time","AUS Central Standard Time","E. Australia Standard Time","AUS Eastern Standard Time","West Pacific Standard Time","Tasmania Standard Time","Yakutsk Standard Time","Central Pacific Standard Time","Vladivostok Standard Time","New Zealand Standard Time","UTC+12","Fiji Standard Time","Magadan Standard Time","Tonga Standard Time","Samoa Standard Time")]
    [ValidateNotNullOrEmpty()]
    [string]$TimeZone = "Eastern Standard Time"
  ) 
   
  $process = New-Object System.Diagnostics.Process 
  $process.StartInfo.WindowStyle = "Hidden" 
  $process.StartInfo.FileName = "tzutil.exe" 
  $process.StartInfo.Arguments = "/s `"$TimeZone`"" 
  $process.Start() | Out-Null 
} # end function Set-TimeZone

Function: New-PSUpdateHelpScheduledTask – Auto Update PowerShell Help

March 1, 2013 3 comments

Probably not of much value to people unless you build a fair amount of servers and have it scripted, but…

One thing you want to do with servers running PowerShell v3.0, such as Windows Server 2012, is to regularly run Update-Help from a PowerShell session to update the help files PowerShell uses for various modules. But this is something that can be easily forgotten, and, who wants to manually do a recurring task, anyways?

Here is a function you can toss in your server build script to create a scheduled task that will automatically update PowerShell help every day at 7pm. The task runs as ‘system’, so we don’t have to worry about storing credentials. Here’s the function

function New-PSUpdateHelpScheduledTask {
    $TaskArguments = '-NonInteractive -WindowStyle Normal -NoLogo -NoProfile -Command "& {Update-Help -Force}"'            
    $TaskProgram =  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"            
    $TaskAction = New-ScheduledTaskAction -Execute $TaskProgram -Argument $TaskArguments
    $TaskTrigger = New-ScheduledTaskTrigger -Daily -At 19:00
    Register-ScheduledTask -TaskName "Update PowerShell Help" -Action $TaskAction -Trigger $TaskTrigger -RunLevel Highest -User "system"
} # end function New-PSUpdateHelpTask

and merely call it using

New-PSUpdateHelpScheduledTask

You'll notice a new scheduled task in Task Scheduler, and we see that it completed successfully.
<a href="http://www.ehloworld.com/wp-content/uploads/2013/02/Update-PowerShell-Help.png"><img class="alignnone size-medium wp-image-1732" alt="Update PowerShell Help" src="http://www.ehloworld.com/wp-content/uploads/2013/02/Update-PowerShell-Help-300x195.png" width="300" height="195" /></a>

Just a couple of lines of code and we’ve removed the need to manually run Update-Help on a server.

But what if you don’t use a script to build your servers (you really should)? We can take the code within the function and just paste it into PowerShell:

$TaskArguments = '-NonInteractive -WindowStyle Normal -NoLogo -NoProfile -Command "& {Update-Help -Force}"'            
$TaskProgram =  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"            
$TaskAction = New-ScheduledTaskAction -Execute $TaskProgram -Argument $TaskArguments
$TaskTrigger = New-ScheduledTaskTrigger -Daily -At 19:00
Register-ScheduledTask -TaskName "Update PowerShell Help" -Action $TaskAction -Trigger $TaskTrigger -RunLevel Highest -User "system"

Hope this helps!

Script: Set-Cs2013Features.ps1 – Easily Install Prerequisites and Tools for Microsoft Lync Server 2013

February 8, 2013 31 comments

Description

This script will assist in getting servers ready for the installation of Microsoft Lync Server 2013 on Windows Server 2012. This includes the operating system prerequisites, SQL Express (where necessary), Silverlight, and more. Some post installation options are also available, and include Microsoft tools such as the debugging tools, the Best Practices Analyzer (BPA), Connectivity Analyzer, and more. Where the script needs files available online, it will automatically download them. More options will be added as I have time, and can properly test. This includes Edge, Director, and Mediation server prerequisites, and more tools. If you have suggestions, please feel free to comment below.

The current options are:

1. Director – Installs the OS prerequisites and SQL Express instances required to install this role.

2. Edge – Installs the OS prerequisites and SQL Express instances required for this role.

3. Front End – includes the Operating System prerequisites, Microsoft Silverlight, as well as the installation of SQL Express SP1 and creation of the various required instances. The SQL Express installs are done because Lync Server installs the RTM version by default. So installing the SP1 version saves a long update later. Note that each instance takes 3-5 minutes to install. Enterprise edition servers have two instances, RTCLocal and LyncLocal, and Standard edition servers also have the RTC instance. See the syntax and example sections below on how to call the script for the two types of servers.

4. Mediation – still being tested to make sure I didn’t miss something.

5. Office Web App – Installs the OS prerequisites required, then installs the Office Web App binaries, and then installs two recent updates. Everything needed to deploy an Office Web Apps server.

6. Persistent Chat - Installs the OS prerequisites and SQL instance required for this role.

7. Lync Server 2013 Resource Kit - tools that make troubleshooting and administrating a Lync environment easier, such as Address Book config, etc.

8. Lync Server 2013 Persistent Chat Resource Kit – tools useful for Persistent Chat environments.

9. Lync Server 2013 Debugging Tools - includes the logging tools such as OCSLogger and Snooper. Helpful for troubleshooting.

10. Lync Server 2013 Stress and Performance Tool – prepare, define, and validate performance

11. Lync Server 2013 Best Practices Analyzer – this tool helps identify any issues from a best practices perspective

12. Lync Server Connectivity Analyzer – identifies any issues that may result in connectivity problems for mobility clients including the Lync Windows Store app

13 Create Shutdown, Logoff, and Restart tiles on desktop – this is a streamlined version of Create a Shutdown/Restart/Logoff Windows 8 Tile for the Start menu (PowerShell) that puts easy to reach Shutdown, Restart, and Logoff tiles on the Start screen. In version 1.1, this was changed from the Start page of the logged on user who runs the script to the desktop and start page of all users.

14. Create scheduled task to automatically update PowerShell help files daily. I discuss this in Function: New-PSUpdateHelpScheduledTask – Auto Update PowerShell Help

15. Launch Windows Update

16. Install/Update Lync Server 2013 Documentation Help

18. Install Microsoft Network Monitor 3.4

19. Add custom Scheduler simple URL – if you’d like to have a simple URL for the scheduler app, such as scheduler.contoso.com, this option will handle the configuration of that. Note that this option requires that the simple URL provided be in the Subject Alternative Names (SAN) list of the certificate on your Front End servers. See Understanding the Lync Web Scheduler for additional info.

20. Install SQL Server 2012 Management Studio

21 Install telnet client

Simply choose your desired option. When the script is finished, it will return to the menu.

Note: The installation of some Lync Server 2013 roles requires some .Net 3.5 components, which are not installed in Windows Server 2012 by default. So the script will need to know where your Server 2012 installation media is. The script defaults to d:, but can be configured for other locations.

The script will also create a log file that can be used for troubleshooting. The log file is created in the same folder that the script is in.

Syntax

C:\Set-Cs2013Features.ps1 [[-TargetFolder] ] [[-Win2012Source] ] [[-SQLPath]] [-WhatIf] [-Confirm]

Examples

Set-Cs2013Features.ps1

This will launch the script with the default options for Enterprise edition servers

Set-Cs2013Features.ps1 -Win2012Source e:

This will launch the script using the e: drive for the source of the Windows Server 2012 installation files

Set-Cs2013Features.ps1 -sqlpath "d:\sqlexpress"

This will install any related SQL Express instances to the specified path

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.

Download

v1.5 – 05-10-2013 Set-Cs2013Features.v1.5.zip

v1.4 – 05-03-2013 Set-CsLync2013Prerequisites.v1.4.zip

v1.3 – 04-29-2013 Set-CsLync2013Prerequisites.v1.3.zip

v1.2 – 04-01-2013 Set-CsLync2013Prerequisites.v1.2.zip

v1.1 – 02-28-2013 Set-CsLync2013Prerequisites.v1.1.zip

v1.0 – 02-08-2013 Set-CsLync2013Prerequisites.v1.0.zip

Changelog

See the changelog for information on what’s changed/included in each version.

Finding a Domain Controller Within the Same AD Site via PowerShell

November 7, 2012 Leave a comment

In Exchange Management Shell and Lync Server Management Shell, you can target many cmdlets at specific domain controllers. This is crucial, especially in larger environments, if you need to make sure AD replication delays aren’t going to cause issues. An example is enabling a user for Lync using Enable-CsUser, then trying to use Set-CsUser or Grant-CsExternalAccessPolicy. The second will fail if it sends it to a different domain controller than the first, and replication hasn’t completed. So, the -DomainController switch can be used. Just send each command to the same DC, and even in rapid succession, you’ll succeed.

However, if you’re reusing your scripts or functions, especially in different environments, you have to find a valid DC in same AD site, put that into the script/function, and go. What a waste of time!

We can streamline the process with just a couple lines of code. First, we use Get-WMIObject to retrieve info on the local computer.

[object]$ComputerInfo = (Get-WMIobject -class "Win32_NTDomain" -namespace "root\CIMV2")

Next, we assign a variable, $ADSite, to the site name returned from the first line

[string]$ADSite = $ComputerInfo[1].ClientSiteName

Then we get a list of DCs in that same site

$DCsInSite = (Get-ADDomainController -Filter {Site -eq "$ADSite"})

And lastly, we randomly pick a DC from that list

[string]$QueryDC = ($DCsInSite | Get-Random).name

$QueryDC can now be used in your code, such as

Enable-CsUser [user] -RegistrarFQDN [fqdn] -SipAddressType [SIP address type] -DomainController $QueryDC

And that’s it. The only real requirement here is that the ActiveDirectory module be loaded, so that the Get-ADDomainController cmdlet works. This is easy:

Import-Module ActiveDirectory

In its entirety, here is the code:

Import-Module ActiveDirectory
[object]$ComputerInfo = (Get-WMIobject -class "Win32_NTDomain" -namespace "root\CIMV2") 
[string]$ADSite = $ComputerInfo[1].ClientSiteName 
$DCsInSite = (Get-ADDomainController -Filter {Site -eq "$ADSite"}) 
[string]$QueryDC = ($DCsInSite | Get-Random).name

 

Function: New-SignedScript – Easily Sign One or Many Scripts with Your Code Signing Cert

September 20, 2012 Leave a comment

Signs a PowerShell script with a code signing certificate.

Syntax

New-SignedScript [[-path] ] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ] [-WhatIf] [-Confirm]

Detailed Description

One of the concerns about using a PowerShell script is that it often requires the user to change the Execution Policy on the machine the script is running on. This can cause security concerns, because when the Execution Policy is lowered, any script can run, including those with malicious intent. For more information on setting the Execution Policy, see Set-ExecutionPolicy.

Of course, you need a code signing certificate in order to sign scripts. Fellow Exchange MVP Mike Pfeiffer wrote an informative article, Obtaining a Code Signing Certificate and Signing PowerShell Scripts that covers using an internal Certificate Authority. Third party Certificate Authorities (CAs) such as Digicert also provide code signing certificates. I can’t recommend Digicert enough. I have both a standard code signing certificate and an Extended Validation code signing certificate.

But signing scripts manually can be a little cumbersome. This function gets the current code signing certificate, verifies it’s not expired, and then signs the script. The script will only sign .ps1 files, and will not attempt to sign a script that’s already signed.

Example

New-SignedScript -path [path to script]

such as

New-SignedScript -path myscript.ps1

You can also pipeline files to this function, for example:

Get-Item *.ps1 | New-SignedScript

Installation

Nothing special here. Once you have a valid code signing certificate installed, the function should work as designed.

Download

v1.0 – New-SignedScript.v1.0.zip

Changelog

None at this time.

Categories: PowerShell Tags: , ,

New-ExpiringCertificatesReminder.ps1 – changelog

September 14, 2012 Leave a comment

This is the changelog page for New-ExpiringCertificatesReminder.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.0 – 09-11-2012

  1. Initial version
Categories: PowerShell Tags: , ,

Script: New-ExpiringCertificatesReminder.ps1 – Receive a Reminder When Certificates Have Expired/Are Expiring

September 14, 2012 Leave a comment

Detailed Description

Sometimes we’re so deep in projects or putting out fires that some things just get forgotten, or we don’t get that far down the “to-do” list. Some of those things aren’t that big of a deal and don’t impact users. Other tasks can have drastic impact. Such as forgetting to renew your server certificates. It’s true that some services like the phenomenal Digicert will remind-you-to-death about certs that are expiring. But not all services do that, or they do it once and are forgotten. Other certs, like internal certs, don’t generate a reminder – and some environments don’t allow, or aren’t configured to automatically renew internal certificates. So this lazy, forgetful guy decided to do something about that. A script was born.

This script monitors certificates in the Local Machine store on the local server, and sends a reminder when a cert is expiring soon, or has already expired. An example is shown below.

Sample email about an expired certificate

Sample email about an expired certificate

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.

Download the script and ImageFiles.zip files from the DOWNLOAD section below. Copy the image files to a location available to all users who will receive the reminder email. I suggest a web server with public access. NOTE: These images are the SAME files and names as the ones for New-PasswordReminder.ps1, so you can use the same path if you use both scripts.

Open the script in a text editor and edit the variables in the param block to suit your needs. At a bare minimum, you need to adjust:

  • $Company – this should be your company name
  • $PSEmailServer – this is the email server the script will send the emails to
  • $EmailFrom – this is the SMTP address that the emails will come FROM
  • $EmailTo – set this to the SMTP address of the user/distribution group that should receive the reminder emails
  • $HelpDeskPhone – if not empty, this appears in the email message
  • $HelpDeskURL – if not empty, should be a URL to a web version of the email. If blank, the “If this email does not appear…” and “This email was sent by…” lines shown in the above example are not included.
  • $ImagePath – where the images are stored. This should be publicly reachable for users checking email from mobile devices and web clients

optionally, adjust $threshold from the default 15 to indicate how many days in advance the script should start reminding about an expiring certificate.

Save the script.

If you don’t already have a Receive Connector in Exchange to allow PowerShell scripts to send email, create one using the information at Creating A Receive Connector To Use For Sending Email From PowerShell.

If you have certs that are already expired, or are expiring soon, you can manually run the script to test. To do that, open PowerShell and type

New-ExpiringCertificatesReminder.ps1

Once everything is done, you can run the script in Install mode:

New-ExpiringCertificatesReminder.ps1 -Install

and the script will prompt for the user password, then automatically create a scheduled task on the local server to run every day at 7:30am. You can open the Scheduled Tasks GUI and adjust parameters as needed, but I’ve found the defaults to be fine.

Repeat on any other servers you’d like to monitor.

Download

v1.0 (09-14-2012) - New-ExpiringCertificatesReminder.v1.0

ScriptImages.zip - these are the images specified in the emails

Changelog

See the changelog for information on what’s changed/included in each version.

Categories: PowerShell Tags: ,

New-FirewallRule – changelog

September 14, 2012 Leave a comment

This is the changelog page for New-FirewallRule. 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.0 – 09-14-2012

  1. Initial version
Categories: PowerShell Tags: ,