Scripting – Installing Server Features on Multiple 2008 Servers
Installing server features on multiple servers using a text file and psexec. You can find psexec here.
servers.txt:
server1.contoso.com server2.contoso.com server3.contoso.com
Run the follwing psexec command:
Psexec.exe @Servers.txt ServerManagerCMD.exe -install FS-DFS
For a list of features that can be installed this way run:
ServerManagerCMD.exe -query.
Scripting – ExpressMaint SQL Backups With Email Reports
This script takes full backups of SQL databases, stores the reports, and emails the results. This script makes use of ExpressMaint for backups and Bmail to send emails.
@echo off :: set some stuff SET utilBaseDir=C:\util SET backupBaseDir=C:\db-backups SET reportBaseDir=C:\db-reports SET [email protected] SET [email protected] SET useEmailServer=smtp.contoso.com SET mailServerPort=25 :: backup the db %utilBaseDir%\ExpressMaint.exe -S (local) -D ALL -B %backupBaseDir% -BU Days -BV 14 -V -C -RU Days -RV 14 -R %reportBaseDir% -T DB :: get most recent report file FOR /F "delims=|" %%I IN ('DIR "%reportBaseDir%\*.*" /B /O:D') DO SET NewestFile=%%I :: get current date FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B FOR /F "TOKENS=1,2 DELIMS=/ eol=/" %%A IN ('echo %CDATE%') DO SET dd=%%B FOR /F "TOKENS=2,3 DELIMS=/ " %%A IN ('echo %CDATE%') DO SET yyyy=%%B SET dbReportDate=%mm%-%dd%-%yyyy% :: email report %utilBaseDir%\bmail.exe -s %useEmailServer% -p %mailServerPort% -t %reportEmailTo% -f %reportEmailFrom% -a "%dbReportDate% - Backup Report" -m %reportBaseDir%\%newestfile%.
Exchange – Convert Mailbox Enabled User to Mail Enabled User
This powershell script will convert a mailbox enabled user into a mail enabled user. Please test before you use this script, it’s provided as is, I am in no way responsible if you break stuff, and there is a good chance you will if you don’t test.
<# .SYNOPSIS Convert mailbox enabled user into mail enabled user .DESCRIPTION Automates converstion of mailbox enabled user account into a mail enabled user account .NOTES Author: Jonathan - [email protected] .LINK http://elderec.org .PARAMETER Identity Identity of mailbox enabled user being converted .PARAMETER EmailAddress The users primary email address, this will be used as the external address on the new mail enabled user .PARAMETER DomainController The domain controller to use .EXAMPLE .\Convert-MBUtoMEU.ps1 -Identity "Jon Q. User" -EmailAddress "[email protected]" #> param ( [parameter(Mandatory=$true, HelpMessage="Enter the Identity of the user to convert")][string]$Identity, [parameter(Mandatory=$true, HelpMessage="Enter the users primary email address")][string]$EmailAddress, [parameter(Mandatory=$true, HelpMessage="Enter the domain controller to use")][string]$DomainController ) # get the user $user = Get-Mailbox -DomainController $DomainController -Identity $Identity # get curret email addresses $currAddresses = $user.EmailAddresses # get the X500 address $legDn = $user.LegacyExchangeDn # add the legacy DN to the list $currAddresses.add("X500:$legDn") # disable the old mailbox Disable-Mailbox -DomainController $DomainController -Identity $user # Mail enable the user account Enable-MailUser -Identity $thisUser -DomainController $DomainController -ExternalEmailAddress $EmailAddress # get the new user $newUser = Get-MailUser -DomainController $DomainController -Identity $Identity # set the new addresses Set-MailUser -DomainController $DomainController -Identity $newUser -EmailAddressPolicyEnabled $false -ExternalEmailAddress $EmailAddress -EmailAddresses $currAddresses.
Powershell – Email Password Expiration Reminders
Combination of scripts to send HTML formatted reminder emails to users whos passwords are about to expire. These scripts are shamelessly stolen from a few places on the web, with minor modifications. I’ve got this running daily as a scheduled task to send email reminders to users. This helps when users don’t logout of their computers, which means they don’t get the expiring password notification.
Make sure you modify the XSL template to meet your requirements, you will also need to add a valid path to a logo image to Send-HTMLFormattedEmail.ps1.
pw-expiry-notice.ps1
# Requires Active Directory Module for Windows Powershell # Found in Windows Features-->Remote Server Admin tools-->Role Administration Tools--> AD DS and AD LDS Tools # Uses HTML email script found at: http://community.spiceworks.com/scripts/show/1037-send-html-emails-via-powershell Import-Module ActiveDirectory Import-Module c:\scripts\pw-expired\Send-HTMLFormattedEmail.ps1 # Debug mode. Use $debugemail to send all emails to a test address $debug = $false $debugemail = "[email protected]" # set the domain controller to user $dc = "someDC.contoso.com" # SMTP Server address $smtp = 'smtp.contoso.com' #Sender details $fromemail = "[email protected]" $fromdisplay = "Contoso IT Department" # Path to the XSL template for email $xsltemplate = "c:\scripts\pw-expired\pw-expired.xsl" # Get all *enabled* users in domain who have a password expiration, a passwordlastset timestamp, who are allowed to change password and have an email address to send the notice to. Get-ADUser -Server $dc -filter * -properties PasswordNeverExpires,PasswordLastSet,EmailAddress,CannotChangePassword,Enabled | ?{($_.PasswordLastSet) -and ($_.EmailAddress) -and ($_.CannotChangePassword -eq $False) -and ($_.Enabled -eq $true) -and ($_.PasswordNeverExpires -ne $true)} |foreach { # Get your current password policy how many days old $PasswordPolicy = Get-ADDefaultDomainPasswordPolicy # Get the last time they changed password $PasswordLastSetDate=$_.PasswordLastSet # Get Today for something to compare against $Today=Get-Date # Find out when password is supposed to expire $ExpireDate=$PasswordLastSetDate + $PasswordPolicy.MaxPasswordAge # How many days left before expires. We can use .days to get a round number for email usage, .totaldays for computational purposes. $PasswordAgeLeft=$ExpireDate-$Today # Get a friendly name string, because it doesn't work inside the quotes when passed through as $_.givenName for some reason that's above my skill level 😛 $FriendlyName=$_.givenName # Call html email function (seperate module) depending on number of days left, adjusting subject etc. Below sends email at 14 days, and then at 5 days onwards with a specific one for less then 24 hours left. # can add -CC or -BCC parameters as required. # debug is false, send mail to the users if ($debug -ne $true) { if ($PasswordAgeLeft.TotalDays -le 15 -and $PasswordAgeLeft.TotalDays -ge 13){ Write-Host "Sending email to $FriendlyName ..." Send-HTMLFormattedEmail -To $_.EmailAddress -ToDisName $_.givenName -From $Fromemail -FromDisName $Fromdisplay -Subject "Your Password is due to expire soon, $FriendlyName" -Content $PasswordAgeLeft.days -XSLPath $xsltemplate -Relay $smtp } elseif ($PasswordAgeLeft.Totaldays -le 1 -and $PasswordAgeLeft.TotalDays -ge 0) { Write-Host "Sending email to $FriendlyName ..." Send-HTMLFormattedEmail -To $_.EmailAddress -ToDisName $_.givenName -From $Fromemail -FromDisName $Fromdisplay -Subject "Your Password expires today, $FriendlyName . Read this to be able to continue to work" -Content $PasswordAgeLeft.days -XSLPath $xsltemplate -Relay $smtp } elseif ($PasswordAgeLeft.Totaldays -le 5 -and $PasswordAgeLeft.TotalDays -ge 1) { Write-Host "Sending email to $FriendlyName ..." Send-HTMLFormattedEmail -To $_.EmailAddress -ToDisName $_.givenName -From $Fromemail -FromDisName $Fromdisplay -Subject "Your Password is due to expire very soon, $FriendlyName" -Content $PasswordAgeLeft.days -XSLPath $xsltemplate -Relay $smtp } else {} } # debug is true, send all emails to a test address else { if ($PasswordAgeLeft.TotalDays -le 15 -and $PasswordAgeLeft.TotalDays -ge 0) { Send-HTMLFormattedEmail -To $debugemail -ToDisName $_.givenName -From $Fromemail -FromDisName $Fromdisplay -Subject "Your Password is due to expire soon, $FriendlyName" -Content $PasswordAgeLeft.days -XSLPath $xsltemplate -Relay $smtp } } }
Send-HTMLFormattedEmail.ps1
# Based on code by tysonkopczynski (http://poshcode.org/1035) # Added Inline attachments by Simon Henderson #------------------------------------------------- # Send-HTMLFormattedEmail #------------------------------------------------- # Usage: Send-HTMLFormattedEmail -? #------------------------------------------------- function Send-HTMLFormattedEmail { <# .Synopsis Used to send an HTML Formatted Email. .Description Used to send an HTML Formatted Email that is based on an XSLT template. .Parameter To Email address or addresses for whom the message is being sent to. Addresses should be seperated using ;. .Parameter ToDisName Display name for whom the message is being sent to. .Parameter CC Email address if you want CC a recipient. Addresses should be seperated using ;. .Parameter BCC Email address if you want BCC a recipient. Addresses should be seperated using ;. .Parameter From Email address for whom the message comes from. .Parameter FromDisName Display name for whom the message comes from. .Parameter Subject The subject of the email address. .Parameter Content The content of the message (to be inserted into the XSL Template). .Parameter Relay FQDN or IP of the SMTP relay to send the message to. .XSLPath The full path to the XSL template that is to be used. #> param( [Parameter(Mandatory=$True)][String]$To, [Parameter(Mandatory=$True)][String]$ToDisName, [String]$CC, [String]$BCC, [Parameter(Mandatory=$True)][String]$From, [Parameter(Mandatory=$True)][String]$FromDisName, [Parameter(Mandatory=$True)][String]$Subject, [Parameter(Mandatory=$True)][String]$Content, [Parameter(Mandatory=$True)][String]$Relay, [Parameter(Mandatory=$True)][String]$XSLPath ) try { #logo used in signature $Logopic = "c:\\scripts\\pw-expired\\logo.png" $Message = New-Object System.Net.Mail.MailMessage # add the attachment, and set it to inline. $Attachment = New-Object Net.Mail.Attachment("c:\\scripts\\pw-expired\\logo.png") $Attachment.ContentDisposition.Inline = $True $Attachment.ContentDisposition.DispositionType = "Inline" $Attachment.ContentType.MediaType = "image/jpg" $Logo = "cid:logo" # Load XSL Argument List $XSLArg = New-Object System.Xml.Xsl.XsltArgumentList $XSLArg.Clear() $XSLArg.AddParam("To", $Null, $ToDisName) $XSLArg.AddParam("Content", $Null, $Content) $XSLArg.AddParam("Logo", $Null, $Logo) # Load Documents $BaseXMLDoc = New-Object System.Xml.XmlDocument $BaseXMLDoc.LoadXml("<root/>") $XSLTrans = New-Object System.Xml.Xsl.XslCompiledTransform $XSLTrans.Load($XSLPath) #Perform XSL Transform $FinalXMLDoc = New-Object System.Xml.XmlDocument $MemStream = New-Object System.IO.MemoryStream $XMLWriter = [System.Xml.XmlWriter]::Create($MemStream) $XSLTrans.Transform($BaseXMLDoc, $XSLArg, $XMLWriter) $XMLWriter.Flush() $MemStream.Position = 0 # Load the results $FinalXMLDoc.Load($MemStream) $Body = $FinalXMLDoc.Get_OuterXML() # Populate the Message. $html = [System.Net.Mail.AlternateView]::CreateAlternateViewFromString($body, $null, "text/html") $imageToSend = new-object system.net.mail.linkedresource($Logopic,"image/jpg") $imageToSend.ContentID = "logo" $html.LinkedResources.Add($imageToSend) $message.AlternateViews.Add($html) $Message.Subject = $Subject $Message.IsBodyHTML = $True # Add From $MessFrom = New-Object System.Net.Mail.MailAddress $From, $FromDisName $Message.From = $MessFrom # Add To $To = $To.Split(";") # Make an array of addresses. $To | foreach {$Message.To.Add((New-Object System.Net.Mail.Mailaddress $_.Trim()))} # Add them to the message object. # Add CC if ($CC){ $CC = $CC.Split(";") # Make an array of addresses. $CC | foreach {$Message.CC.Add((New-Object System.Net.Mail.Mailaddress $_.Trim()))} # Add them to the message object. } # Add BCC if ($BCC){ $BCC = $BCC.Split(";") # Make an array of addresses. $BCC | foreach {$Message.BCC.Add((New-Object System.Net.Mail.Mailaddress $_.Trim()))} # Add them to the message object. } # Create SMTP Client $Client = New-Object System.Net.Mail.SmtpClient $Relay # Send The Message $Client.Send($Message) } catch { throw $_ } $attachment.Dispose() #dispose or it'll lock the file }
pw-expired.xsl
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output media-type="xml" omit-xml-declaration="yes" /> <xsl:param name="To"/> <xsl:param name="Content"/> <xsl:param name="Logo"/> <xsl:attribute-set name="image-style"> <xsl:attribute name="style">float:left; margin-right:0px; margin-bottom:0px</xsl:attribute> <xsl:attribute name="alt">green</xsl:attribute> <xsl:attribute name="src"><xsl:value-of select="$Logo" /></xsl:attribute> <xsl:attribute name="title">SP logo</xsl:attribute> </xsl:attribute-set> <xsl:template match="/"> <html> <head> <title>Your Password is due to Expire!</title> </head> <body> <div width="400px"> <p>Hello <xsl:value-of select="$To" />,</p> <p></p> <p>Your windows password will expire in <xsl:value-of select="$Content" /> days.</p> <p></p> <p>This password is used log in to Contoso PCs and access email, VPN, and various intranet sites.</p> <p></p> <p>If you are working on an Office computer, please press CTRL-ALT-DELETE and choose change password. Follow the instructions to set your new password. </p> <p></p> <p>If you use web based Outlook, please visit <a href="https://mail.contoso.com/owa/">https://mail.contoso.com/owa/</a>, login and follow the steps outlined below. <ol> <li>Log into your e-mail account.</li> <li>Click Options and then 'See all options' in the top right of the window.</li> <li>Click 'Change your password' on the right column.</li> <li>Enter your current password, and provide a new password in the required fields.</li> <li>Click Save.</li> </ol> </p> <p> <strong>PASSWORD REQUIREMENTS</strong> </p> <p> Your Password... </p> <p> <ul> <li>must be at least 8 characters long</li> <li>must contain any 3 of the following: <ul> <li>upper case letter</li> <li>lower case letter</li> <li>number</li> <li>special character (like !@#$%^)</li> </ul> </li> <li>must not be the same as your previous passwords</li> <li>must not contain any part of your name</li> </ul> </p> <p> <strong>If you do not change your password it will expire and you will be unable to work until it is changed!</strong><br /> </p> <p> If any point you have any questions or concerns please open a help desk ticket by replying to this email, or contact the Helpdesk at 1-877-997-8715 </p> <p></p> <Address> Many thanks,<br /> Contoso IT Team<br /> </Address> <xsl:element name="img" use-attribute-sets="image-style"></xsl:element> </div> </body> </html> </xsl:template> </xsl:stylesheet>.
Exchange 2010 – Watch PST Import Request Progress
Quick Powershell script to watch the status of import requests in Exchange 2010.
<# .SYNOPSIS Detailed stats on a single PST import request .DESCRIPTION Watch the status of a single PST import request .NOTES Author: Jonathan .LINK http://elderec.org .PARAMETER Identity Identity of Mailbox Import Request .EXAMPLE .\Watch-ImportRequest.ps1 -Identity "Jon Q. User" #> param ( [parameter(Mandatory=$true, HelpMessage="Enter the Identity of the active move request.")][string]$Identity ) do { $mbMove = Get-MailboxImportRequestStatistics -Identity $Identity $stat = "Importing PST | $Identity" $act = "Duration: " + [string]$mbMove.OverallDuration + " | " + $mbMove.PercentComplete + "% complete" Write-Progress -activity $act -Status $stat -percentComplete $mbMove.PercentComplete } Until ( $mbMove.Status -eq "Completed" ).
Exchange – Find All Disabled User Accounts NOT Hidden From The Address Book
Quick Powershell one-liner to find disabled accounts that are not hidden from the GAL.
Get-Mailbox -Filter{(HiddenFromAddressListsEnabled -eq $false) -AND (UserAccountControl -eq "AccountDisabled, NormalAccount")}.
Powershell – Backup Multiple DHCP Databases to SMB Share
Quick script to backup DHCP databases from various Windows 2008R2 site servers to a central file share.
# server site codes $siteCodes = @('PDX','NYC','LAX') # set backup path $backupRoot = "\\my-fps.contoso.com\some-share\backups\dhcp" # copy the DHCP backups over to MY-FPS ForEach ($x in $siteCodes) { $path = "\\$x-ad.contoso.com\c$\windows\system32\dhcp\backup" Copy-Item $path -Destination $backupRoot\$x -Recurse -Force -ErrorAction SilentlyContinue }.
Hyperion – SmartView Connection Screen Box is Blank in Excel on Windows 64 bit
Using Office 2007 or Office 2010, the SmartView Connection Manager is blank on the right pane of the connection box. This is due to 64-bit Windows not supporting multiple nested child windows as far as resizing is concerned due to the kernel stack overflow.
The cause of this problem has been identified and verified as an Oracle unpublished Bug 9451307 – SMARTVIEW INSTALLED ON 64 BIT SHOWS ONLY BLANK ON RIGHT PANE IN CONNECTION BOX.
This issue has been fixed in the SmartView v11.1.1.3.01 Patch Release, Patch:9779433 – Oracle’s Hyperion Smart View for Office 11.1.1.3.01 Service Fix. This patch can be obtained from My Oracle Support.
.Exchange 2010 – Add Calendar Permissions to Members of AD Group
I was recently tasked with adding calendar permissions for the members of an AD group to a specific users mailbox. The following Powershell snippet will grant “Editor” permissions on the “someuser” calendar for the members of the AD group named “Some Group”.
This snippet makes use of the Get-ADGroupMember and the Get-Mailbox cmdlets.
Get-ADGroupMember -Identity "Some Group" | ForEach-Object { $mb = Get-Mailbox -Identity $_.distinguishedName Add-MailboxFolderPermission -Identity "someuser:\Calendar" -User $mb.Alias -AccessRights Editor }.
Exchange 2010 – Monitoring The Progress of Mailbox Move Requests
In Exchange 2010 mailbox moves are asynchronous and are performed by the Microsoft Exchange Mailbox Replication service (MRS). Unfortunately there is no built in way to watch the mailbox move complete with a progress bar. Below is a Powershell script that will present a status bar for the mailbox move.
<# .SYNOPSIS Detailed stats on a single mailbox move .DESCRIPTION Watch the status of a single mailbox move .NOTES Author: elderec.org .LINK http://elderec.org .PARAMETER Identity Identity of Mailbox Move Request .EXAMPLE .\Watch-MailboxMove.ps1 -Identity "John Q. User" #> param ( [parameter(Mandatory=$true, HelpMessage="Enter the Identity of the active move request.")][string]$Identity, [parameter(Mandatory=$false, HelpMessage="Which Domain Controller are we using?")][string]$DomainController ) do { $mbMove = Get-MoveRequestStatistics -Identity $Identity -DomainController $DomainController $stat = [string]$mbMove.BytesTransferred + " - " + [string]$mbMove.ItemsTransferred + " of " + [string]$mbMove.TotalMailboxItemCount + " items." $act = "Moving " + $mbMove.DisplayName + "'s mailbox | " + [string]$mbMove.OverallDuration + " | " + $mbMove.PercentComplete + "% complete" Write-Progress -activity $act -Status $stat -percentComplete $mbMove.PercentComplete } Until ( $mbMove.Status -eq "Completed" ).
subscribe via RSS