Archive for category Admin Tools

Powershell Script to Disable inactive Users

Purpose:
Disable users that have been inactive for 90 days.

Notes:
Have not improved format yet.

Must be run on a DC with Domain Admin rights.

# Get today's date
$date = get-date

# Set variable LLTSlimit to today's date minus 90 days
$LLTSlimit = (Get-Date).AddDays(-90).ToFileTimeUTC().ToString()

# Set variable LDAPfilter as a LDAP filter to only find ACTIVE user accounts (useraccountcontrol piece) that have a lastlogontimestamp of older than 90 days
$LDAPFilter = "(&(objectCategory=Person)(objectClass=User)(lastlogontimestamp<=$LLTSlimit)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" #output LDAPfilter to txt file for loop dsquery * domainroot -filter $LDAPFilter -limit 0 > D:\scripts\AD Auto Disable\ADUserstoDisable.txt

#if LDaPfilter is not null, we will disable some accounts and send a email else do nothing.
if (($ldapcontent = get-content "D:\scripts\AD Auto Disable\ADUserstoDisable.txt") -ne $NULL)
{

    # Pre-create file to store query results
ECHO "Summary of Users Disabled Due To Inactivity" >  D:\scripts\AD Auto Disable\AutoDisableResults.txt
ECHO "*--------------------------------------------------------*" >> D:\scripts\AD Auto Disable\AutoDisableResults.txt

#Loop through the users that need to be disabled one at a time
FOREACH ($f in get-content D:\scripts\AD Auto Disable\ADUserstoDisable.txt)
{
#Add the user to be disabled to txt file to be emailed out.
$f>>D:\scripts\AD Auto Disable\AutoDisableResults.txt

#get the old description so it can be appended
$olddesc = dsget user $f -desc
$olddesc > D:\scripts\AD Auto Disable\olddesc.txt
$processolddesc = get-content "D:\scripts\AD Auto Disable\olddesc.txt"
$processolddesc = $processolddesc[1]

Update:
There is a better version of this script over at vNucleus.com that David wrote:
http://vnucleus.com/2011/07/use-powershell-to-auto-disable-inactive-active-directory-accounts/

David recently sold his domain and this link no longer works.  As soon as he republishes his site I’ll update the link.

A newer version can now be found here: http://wp.me/p1VY3A-7R

Advertisements

Leave a comment

Simple Powershell Script to Disable PCs that have been inactive in AD for 90 Days.

Purpose:
Find PC’s that have been inactive for more than 90 days

Notes:
I haven’t formated this script in the typical fashion I normally do.

Must be run on a DC with Domain Rights.

# Get today's date
$date = get-date

# Set variable LLTSlimit to today's date minus 90 days
$LLTSlimit = (Get-Date).AddDays(-90).ToFileTimeUTC().ToString()

# Set variable LDAPfilter as a LDAP filter to only find ACTIVE user accounts (useraccountcontrol piece) that have a lastlogontimestamp of older than 90 days
$LDAPFilter = "(&(objectCategory=Computer)(objectClass=User)(lastlogontimestamp<=$LLTSlimit)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

#output LDAPfilter to txt file for loop
dsquery * domainroot -filter $LDAPFilter -limit 0 > D:\scripts\test.txt

#Loop through the computers that need to be disabled one at a time
FOREACH ($f in get-content D:\scripts\test.txt)
{

#disable computer and append to the old description the note about disabling account
dsmod computer $f -disabled yes -desc "$processolddesc - Disabled due to inactivity on $date"

}

exit

Leave a comment

Powershell script to generate and email a DFS Health Report.

Purpose:
This script was used to generate a DFS Health Report and email it to the admin team on a daily basis.

Comments:
I attempted to push the report into the body of the email but Outlook did not like the formatting so instead it was added as an attachment.
This is on a Windows 2008 R2 Server using the old commandline version of DFS and its reporting. The Report does not work in some of the newer version of IE.
To view the report you have to hit F12 and then change the Document Mode: IE quirks to IE5 Quirks

#=====================================================================================================#
#    Copyright 2011 Robert Stacks
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#=====================================================================================================#
# Author: Robert Stacks
# URL: RandomTechMinutia.wordpress.com
# Date: 11/30/2012
# Updated: 11/30/2012
# Version: 0.1
#
# Purpose:
# Generate a DFS Admin Report and Email it to the admin team it must be viewed with IE due to HTML/Java formatting
#=====================================================================================================#

#Get todays Date
$date = Get-Date

#===========================#
#User Adjustable Variables  #
#===========================#

#Mail Server Variables
$SMTPserver = "mail.domain.com"
$from = "DFSReplicationReport@domain.com"
$to = "Youremail@domain.com"
$subject = "DFS Replication Health Report " + $date
$emailbody = "Attached is the Report"

#DFS Info
#Note: $ReplicationGroup=`"Corp Office to Phoenix`", if your group name has no spaces you can remove the `"
#the dfsadmin command can be a little unforgiving about quotes you may have to adjust your values accordingly.

$ReplicationGroup=`"Your Replication Group`"
$MemeberServer="ServerName"
$SaveReportLocation="C:\DFSReports"

#===========================#
#Main Script                #
#===========================#

#Generate DFS Report

dfsradmin health new /RgName:$ReplicationGroup /RefMemName:$MemeberServer /repname:$SaveReportLocation

# Send email
Send-MailMessage -From $from -To $to -SmtpServer $SMTPserver -Subject $subject -Body "Attached is the DFS Health Report. It must be viewed in IE" -Attachments ("C:\DFSReports\Health-Corp Office to Phoenix.html")

3 Comments

Powershell / Powercli script to report on VMs and their VMDKs

Here is a report I put together to quickly view all VMs their VMDKs and the Datastores those VMDKs are sitting on. This is not meant to be a report to view total storage or free space on either the VMs or their Datastores, nor are we looking for orphaned vmdk files. Although I may add those features to this report later on.

Update 3/13/2014: Script now reports on Size and how the data is presented has been improved.

Issue: Review VMDK files for any that don’t have the same name as the VM names in VCenter.

Purpose: Scan and report on VMware VM’s VMDKs and what Datastores they are tied to.

Side Notes:

  • You must have Powercli installed on the machine this report runs off of.
  • The admin account used must have enough permissions to run the given commands.
  • It is possible to have two VMs in vCenter with the same name. So in the report you may see a single server when in fact it is two separate servers.
  • If that happens you’ll see a single instance of that VM’s name with more than the expected number of disk.
#=====================================================================================================#
# Author: Robert Stacks
# Date: 7/18/2012
# Updated: 3/13/2012
# Verson: 1.1
#
# Purpose: 
# Scan and report on Datastores, and related VM's VMDK visible to vCenter
# 
# Updates:
# 3/12/2012
# - Added a column to show the current host ESXi server, Split Folder from VMDK info, and also added size
# - Fixed some spelling and updated comments
# - Fixed some flow logic and adjusted table row color, table padding, and sizing.
#=====================================================================================================#

#Add Snapins
Add-PSSnapin VMware.VimAutomation.Core

#===========================#
#User Adjustable Variables  #
#===========================#

#Vcenter Logon Info
$ESXserver = "vcenterserver.domain.com"
$ESXuser = "username"
$ESXpassword = "password"

#Mail Server Variables
$SMTPserver = "mail.domain.com"
$from = "VMwareReporter@domain.com"
$to = "sysadmins@domain.com"

#===========================#
#Main Script                #
#===========================#

#Determine if already connected to VCenter and if not connect
if ( $DefaultVIServers.Length -lt 1 )
{
  Connect-VIServer -Server $ESXserver -User $ESXuser -Password $ESXpassword -WarningAction SilentlyContinue | Out-Null
}

# Format html report
$htmlReport = @"
<style type='text/css'>
.heading {
 	color:#0B1ABF;
	font-size:14.0pt;
	font-weight:700;
	font-family:Verdana, sans-serif;
	text-align:left;
	vertical-align:middle;
	height:20.0pt;
	width:416pt;
}
.colnames {
 	color:white;
	font-size:11.0pt;
	font-weight:700;
	font-family:Tahoma, sans-serif;
	text-align:center;
	vertical-align:middle;
	border:.5pt solid windowtext;
	background:#730000;
}
.lblueback {
	color:windowtext;
	font-size:10.0pt;
	font-family:Arial;
	text-align:left;
	vertical-align:middle;
	border:.5pt solid windowtext;
	background:#B8CCE4;
}
.greyback {
	color:windowtext;
	font-size:10.0pt;
	font-family:Arial;
	text-align:left;
	vertical-align:middle;
	border:.5pt solid windowtext;
    #background:#D8D8D8;
}

</style>
<table style='border-collapse:collapse;table-layout:auto;width:auto;padding:5px'>
 <tr style='height:15.0pt'>
   <th colspan=6 height=40 width=auto class="heading">
	<center> VM Datastore Report </center></th>
 </tr>
 <tr>
  <th class="colnames">VM Name</th>
  <th class="colnames">Host</th>
  <th class="colnames">DataStore</th>
  <th class="colnames">Folder</th>
  <th class="colnames">FileName</th>
  <th class="colnames">Size/GB</th>
 </tr>
"@

#get a list of VMs
$vmlist = Get-VM -Server $ESXserver | Sort

#counter to manage alternating row color
$colorcounter = 0

#Master part of the script, loops through each VM and creates table with data
ForEach ($vm in $vmlist)
{	
  #If loop to determine color of Rows related to given VM
  if ($colorcounter%2 -eq 0)
	{
		$tablecell = @"
		<td class='lblueback'>
"@
}
  else 
	{ 
		$tablecell = @"
		<td class='greyback'>
"@
}
  
  # Grab VMDK information and the Datastores tied to them.
  $vmdisk = Get-VM $vm | Get-harddisk
  
  # Split out disks where a VM has more than a single disk, also split out the name of the Datastore
  # from the name/path of the vmdk file, then split the Folder Name from the VMDK name.
  $vmdiskDatastore=($vmdisk | %{$_.Filename.Split('[]')[1]})
  $vmdiskfilename=($vmdisk | %{$_.Filename.Split('[]')[2]})
  $vmdiskFolder=($vmdiskfilename | %{$_.Split('/')[0]})
  $vmdiskVMDK=($vmdiskfilename | %{$_.Split('/')[1]})
  $vmdisksize=($vmdisk | %{$_.CapacityKB})
  
  # determine the length of the array so we know if there was more than one hard drive for a given VM.
  $count = $vmdiskfilename.count - 1
  
  # Begin building the html report, inserting the name of the VM in the 1st Column and Host Name into the 2nd 
  $htmlReport = $htmlReport + 
  "<tr>" + $tablecell + $vm.Name + "</td>" +
  $tablecell + $vm.host.Name + "</td>"
  
  # Based on the number of hard drives in the count value the report is generated in one of two ways
  if($count -le 0)
  {
  	# There is only one hard drive so the values will not be in an array we just need to build the table row with data
  	$htmlReport = $htmlReport + 
	$tablecell + $vmdiskDatastore + "</td>" + 
    $tablecell + $vmdiskFolder + "</td>" +
	$tablecell + $vmdiskVMDK + "</td>" +
	$tablecell + $vmdisksize / 1MB + "</tr>"
  }
  else
  {
  	# There is more than one hard drive, because of table formatting we handle the 1st row different from the 2nd row.  Data is in an array.
  	$htmlReport = $htmlReport +
    $tablecell + $vmdiskDatastore[0] + "</td>" + 
    $tablecell + $vmdiskFolder[0] + "</td>" +
	$tablecell + $vmdiskVMDK[0] + "</td>" +
	$tablecell + $vmdisksize[0] / 1MB + "</tr>"
  
  # There is more than one hard drive so we will loop through the array and and place them in the report
 	$x=1
    While($x -le $count)
	{
    	$htmlReport = $htmlReport +
     	"<tr>" + $tablecell + "" + "</td>" + 
		$tablecell + "" + "</td>" +
    	$tablecell + $vmdiskDatastore[$x] + "</td>" + 
    	$tablecell + $vmdiskFolder[$x] + "</td>" +
		$tablecell + $vmdiskVMDK[$x] + "</td>" +
		$tablecell + $vmdisksize[$x] / 1MB + "</tr>"
		$x= $x+1
  	}
   }
   # value used in conjunction with Foreach and if loop to rotate color in table
   $colorcounter = $colorcounter + 1
 }
 
 # We are done gathering data from vCenter so we disconnect
 Disconnect-VIServer -Server $ESXserver -Force:$true -Confirm:$false

# Send email
$subject = "VMware VM Datastore Report"
$emailbody = $htmlReport
$mailer = New-Object Net.Mail.SMTPclient($SMTPserver)
$msg = New-Object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$msg.IsBodyHTML = $true
$mailer.send($msg)

Example of output:
datastorereportexample

11 Comments

PDFCreator – Handy PDF Print Server for Free

Recently I was asked to address a problem where remote users wanted to be able to print from a legacy Unix/Pick system that normally uses IP based printers.  The remote users connecting to the office using a client side VPN solution didn’t have access to a IP based Printer at home and needed another solution to get their printouts.  Management also didn’t want to spend a ton of money on the solution.  Working with the Unix team I came up with the solution to deploy a Microsoft Windows based PDF printer solution using PDFCreator (http://www.pdfforge.org/pdfcreator).  PDFCreator allows you to setup multiple printers that can be pre-configured to print PDFs to a specific file share that you as an admin can then manage share/file permission as normal.  Another benefit, you can configure these PDFs to be encrypted and have a password on them.  You can also manage if the PDFs can be printed or copied etc.

We ended up deploying this on its own file and print server and then mapping the users computers to their own individual share.  Then on the unix side we instructed them to print to a printer that was pointed back to a PDF printer set to print to their share.  Each user has their own PDF password as well to insure if they print to the wrong printer/share someone else couldn’t open their files.

Then I setup a simple windows script to wipe files contained in the shares older than 7 days.

There are a few catches which are not well covered in documentation which I outline below:

Here is a diagram sort of outlining what I’m talking about

The 1st Catch you need to setup PDFCreator to run as a service.  A good how to can be found over on this blog here.  In short:

  1. Install the Server 2003 resource kit (link).
  2. Create the service with SC:sc create pdfcreator start= auto binPath= “C:\Program Files\oldResourceKitTools\srvany.exe” DisplayName= “PDFCreator”Note the space between the equals sign and the value; it actually needs to be done that way, or SC won’t work.
  3. Check that that worked:sc query pdfcreator
  4. Mangle the service appropriately to actually run the server version of PDFCreator:Start the service and test it out – a file sent to the PDFCreator printer on the server should now pop out in whichever directory you specified back in step 1, regardless of whether or not anyone’s logged in at the server’s console.
    • Edit the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\pdfcreator.
    • Add a “Parameters” key.
    • Inside the newly-created key, add a REG_SZ value called “Application”, with the path to the PDFCreator executable as the data.
  5. Start the service and test it out – a file sent to the PDFCreator printer on the server should now pop out in whichever directory you specified back in step 1, regardless of whether or not anyone’s logged in at the server’s console.

The next Catch,  how to set a password on a individual PDF printer, again you have to edit the registry

So for example if you setup a printer and call it prITTEST (Used in my Example)  You would need to edit the key found at HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\PDFCreator\Profiles\prITTEST\Printing\Formats\PDF\Security

Then set the PDFOwnerPasswordString and PDFUserPasswordString with a password.  You also need to enable security by setting PDFOwnerPass, PDFUserPass, and PDFUseSecurity to 1.

One last thing of note, when installing PDFCreator, the ESET AV solution we use in the office reported the program containing a virus.  That said I tested the .exe using several other products and I think this is a false positive.  Likely flagging the Windows Tool bar it wants to install as spam-ware.

, , ,

Leave a comment

Set AD Email Address to PrimarySmtpAddress in matching Exchange Contact

Synopsis
I wrote this little script to address a issue where another admin/help desk/etc created a bunch of exchange contacts for external users and then later we ended up creating some AD accounts for some of those users so they could access some Linux/Unix systems we host. However we ran into a issue where those users had no way to be notified of password’s expire. So to address that I wrote this script Powershell Script to Notify Users of Expired or About to Expire Passwords in Active Directory which worked fine but then I found I couldn’t email some users because I didn’t have a email address for them. I did however have an exchange contact for some of them. So I wrote the follow script to copy their emails from the exchange contact into the AD Email attribute.

Requirements to run script:

Other Notes:
You will see some errors with this script if the Get-MailContact fails to find any info for the user in question. This is ok and is expected.

#Add Snapins
Add-PSSnapin "Quest.ActiveRoles.ADManagement" -ErrorAction SilentlyContinue

$users = Get-QADUser -SearchRoot 'OU=INTERNATIONAL OFFICE USERS,DC=domain,DC=net' -Enabled -PasswordNeverExpires:$false | where {($_.Email -eq $null)}

Foreach ($user in $users)
{
	$contact = Get-MailContact -Identity $user.Name
	if ($contact -ne $null)
	{
		Set-QADUser $user.Name -Email $contact.PrimarySmtpAddress
	}
	
}

Leave a comment

How to fix the issue of a user not showing up in the Global Address book.

This little one liner can possibly fix a issue where a user doesn’t show up in the Global Address book.

To run the following powershell script, you must be a Domain Admin and an Exchange Admin.

get-mailbox -resultsize unlimited | Where-Object {$_.PrimarySMTPAddress -ne $_.WindowsEmailAddress} 
| foreach { set-mailbox $_.identity -windowsemailaddress $_.primarySMTPAddress }

Explanation:
This Script will set the Email address field found in Active Directory Users and Computers for a User/Object that has a email account in Exchange to the same value as that set in Exchange as that of the User/Object’s primary SMTP email address.

This will fix the issues where the users doesn’t show up in the global address book.

Finally after running the script you must update the OAB in exchange and all clients must update their local address books by running send and receive.

MS Technet Support Article
http://support.microsoft.com/kb/936197

, , ,

Leave a comment

Powershell Script to Notify Users of Expired or About to Expire Passwords in Active Directory.

So where I work we use AD for single sign on (sso) for many of our systems both Windows and Nix. Some of our users only access the Nix systems and are not actually on our domain. They have no way of knowing when their passwords are about to expire and when their passwords do expire they just can’t log in without any visible reason why. In order to address that I started looking around the net for a powershell script and found one over at Dan Penning Blog but it didn’t address all of my needs. So using Dan’s script as the basis for a new script I came up with the following.

Synopsis of Goal:
Email the User when their password is about to expire or has expired and Supply a URL Link to reset their password.
Notify the Admin of certain conditions

  • Users Have Expired Passwords And No Primary SMTP Address to notify them
  • Users Password’s is About To Expire That Have No Primary SMTP Address
  • Users With Expired Passwords – Purely to report on it
  • Users Password’s About To Expire
  • Users with no Expiration Date

And Supply the Admin with the Location of the User account in question in the report.

Other Notes:
Included Options in the script without major rewrite

  • Adjust timing to being alerting (default is at 10 days start sending alerts to the user.)
  • Admin report is optional
  • Admin report can be sorted by Password Expiration, First, or Last Name.
  • Alerting Users is optional
  • Assign self service URL
  • Adjustable From Address and Relay Mail Server.
  • Change Font size and style for majority of text
#=====================================================================================================#
#    Copyright 2011 Robert Stacks
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#=====================================================================================================#
# Author: Robert Stacks
# URL: RandomTechMinutia.wordpress.com
# Updated: 06/21/2012
# Version: 1.2
#
# Based on a script by Dan Penning http://danpenning.com
#
# Purpose:
# Powershell script to find out a list of users
# whose password is expiring within x number of days (as specified in $days_before_expiry).
# Email notification will be sent to them reminding them that they need to change their password.
#
# Requirements:
# Quest ActiveRoles cmdlets (http://www.quest.com/powershell/activeroles-server.aspx)
# Powershell 2.0 ~ may work in 1.0 but I haven't tested it.
#
# Script must be run as a user with Permission to view AD Attributes, Domain Admin for example.
#
#=====================================================================================================#
#Add Snapins
Add-PSSnapin "Quest.ActiveRoles.ADManagement" -ErrorAction SilentlyContinue

#Get todays date for use in the script
$date = Get-Date

#===========================#
#User Adjustable Variables  #
#===========================#

# How many Days Advanced Warning do you want to give?
$DaysOfNotice = 10

#Generate a Admin report?
$ReportToAdmin = $true
#$ReportToAdmin = $false

#Sort Report
#===========================#
# 0 = By OU
# 1 = First Name Ascending
# 2 = Last Name Ascending
# 3 = Expiration Date Ascending
# 4 = First Name Descending
# 5 = Last Name Descending
# 6 = Expiration Date Descending
#===========================#
$ReportSortBy=1

#Alert User?
#$AlertUser = $true
$AlertUser = $false

#URL for self Service
$URLToSelfService = "http://"

#Mail Server Variables
$FromAddress = "DoNotReply@yourdomain.com"
$RelayMailServer = "mail.yourdomain.com"
$AdminEmailAddress ="Admin@yourdomain.com"

# Define font and font size
# ` or \ is an escape character in powershell
$font = "<font size=`"3`" face=`"Calibri`">"

# List of users whose Password is about to expire. The following line can be added to limit OU's searched if so desired
#$users += Get-QADUser -SearchRoot 'DN' -Enabled -PasswordNeverExpires:$false | where {($_.PasswordExpires -lt $date.AddDays($DaysOfNotice))}
#$users = Get-QADUser -SearchRoot 'OU= Company USERS,DC=contoso,DC=com' -Enabled -PasswordNeverExpires:$false | where {($_.PasswordExpires -lt $date.AddDays($DaysOfNotice))}
#$users += Get-QADUser -SearchRoot 'OU=INTERNATIONAL OFFICE USERS,DC=contoso,DC=com' -Enabled -PasswordNeverExpires:$false | where {($_.PasswordExpires -lt $date.AddDays($DaysOfNotice))}

# Search Whole Root
$users = Get-QADUser -Enabled -PasswordNeverExpires:$false | where {($_.PasswordExpires -lt $date.AddDays($DaysOfNotice))}

#===========================#
#Main Script                #
#===========================#

# Sort Report
Switch ($ReportSortBy)
{
'0' {$users}
'1' {$users = $users | sort {$_.FirstName}}
'2' {$users = $users | sort {$_.LastName}}
'3' {$users = $users | sort {$_.PasswordExpires}}
'4' {$users = $users | sort -Descending {$_.FirstName}}
'5' {$users = $users | sort -Descending {$_.LastName}}
'6' {$users = $users | sort -Descending {$_.PasswordExpires}}
}

if ($ReportToAdmin -eq $true)
{
#Headings used in the Admin Alert
$Title="<h1><u>Password Expiration Status and Alert Report</h1></u><h4>Generated on " + $date + "</h4>"
$Title+="<font color = red><h2><u>Admin Action Required</h2></u></font>"
$Title+="<font size=`"3`" color = red> An Admin needs to update these accounts so that users can be notified of pending or past password experation<br></font>"
$Title_ExpiredNoEmail="<h3><u>Users Have Expired Passwords And No Primary SMTP to Notify Them</h3></u>"
$Title_AboutToExpireNoEmail="<h3><u>Users Password's Is About To Expire That Have No Primary SMTP Address</h3></u>"
$Title2="<br><br><h2><u><font color= red>No Admin Action Required - Email Sent to User</h2></u></font>"
$Title_Expired="<h3><u>Users With Expired Passwords</h3></u>"
$Title_AboutToExpire="<h3><u>Users Password's About To Expire</h3></u>"
$Title_NoExpireDate="<h3><u>Users with no Expiration Date</u></h3>"
}
#For loop to report
foreach ($user in $users)
{

if ($user.PasswordExpires -eq $null)
{
$UsersList_WithNoExpiration += $user.Name + " (<font color=blue>" + $user.LogonName + "</font>) does not seem to have a Expiration Date on their account.<font color=Green> <br>OU Container: " + $user.DN + "</font> <br>"
}
Elseif ($user.PasswordExpires -ne $null)
{
#Calculate remaining days till Password Expires
$DaysLeft = (($user.PasswordExpires - $date).Days)

#Days till password expires
$DaysLeftTillExpire = [Math]::Abs($DaysLeft)

#If password has expired
If ($DaysLeft -le 0)
{
#If the users don't have a primary SMTP address we'll report the problem in the Admin report
if (($user.Email -eq $null) -and ($user.UserMustChangePassword -ne $true) -and ($ReportToAdmin -eq $true))
{
#Add it to admin list to report on it
$UserList_ExpiredNoEmail += $user.name + " (<font color=blue>" + $user.LogonName + "</font>) password has expired " + $DaysLeftTillExpire + " day(s) ago</font>. <font color=Green> <br>OU Container: " + $user.DN + "</font> <br><br>"
}

#Else they have an email address and we'll add this to the admin report and email the user.
elseif (($user.Email -ne $null) -and ($user.UserMustChangePassword -ne $true) -and ($AlertUser -eq $True))
{
$ToAddress = $user.Email
$Subject = "Friendly Reminder: Your Corporate Password has expired."
$body = " "
$body = $font
$body += "Greetings, <br><br>"
$body += "This is a auto-generated email to remind you (<font color=blue> " + $user.Name + "</font>) that your Corporate Password for account - <font color=red>" + $user.LogonName + "</font> - has expired. <br><br>"
$body += "This means you will not be able to access any secured system hosted at the Corporate Offices.<br><br> You can log into " + $URLToSelfService + " "
$body += "and reset the password yourself, else you are welcome to contact the Service Desk by Phone for assistance."
$body += "<br><br><br><br>"
$body += " "
$body += "<h4>Never Share Your Password With Others!</h4>"
$body += "<h5>Message generated on: " + $date + ".</h5>"
$body += "</font>"

Send-MailMessage -smtpServer $RelayMailServer -from $FromAddress -to $user.Email -subject $Subject -BodyAsHtml  -body $body

}
if ($ReportToAdmin -eq $true)
{
#Add it to a list
$UserList_ExpiredHasEmail += $user.name + " (<font color=blue>" + $user.LogonName + "</font>) password has expired " + $DaysLeftTillExpire + " day(s) ago</font>. <font color=Green> <br>OU Container: " + $user.DN + "</font> <br><br>"
}
}
elseif ($DaysLeft -ge 0)
{
#If Password is about to expire but the user doesn't have a primary address report that in the Admin report
if (($user.Email -eq $null) -and ($user.UserMustChangePassword -ne $true) -and ($ReportToAdmin -eq $true))
{
#Add it to admin list
$UserList_AboutToExpireNoEmail += $user.name + " (<font color=blue>" + $user.LogonName + "</font>) password is about to expire and has " + $DaysLeftTillExpire + " day(s) left</font>. <font color=Green> <br>OU Container: " + $user.DN + "</font> <br><br>"
}
# If there is an email address assigned to the AD Account send them a email and also report it in the admin report
elseif (($user.Email -ne $null) -and ($user.UserMustChangePassword -ne $true) -and ($AlertUser -eq $True) )
{
#Setup email to be sent to user
$ToAddress = $user.Email
$Subject = "Notice: Your Corporate Password is about to expire."
$body = " "
$body = $font
$body += "Greetings, <br><br>"
$body += "This is a auto-generated email to remind you (<font color=blue> " + $user.Name + "</font>) that your Corporate Password for account - <font color=red>" + $user.LogonName + "</font> - will expire in </font color = red>" + $DaysLeftTillExpire +" Day(s). <br><br>"
$body += "This means you will not be able to access any secured system hosted at the Corporate Offices.<br><br> You can log into " + $URLToSelfService + " "
$body += "and reset the password yourself, else you are welcome to contact the Service Desk by Phone for assistance."
$body += "<br><br><br><br>"
$body += "<h4>Never Share Your Password With Others!</h4>"
$body += "<h5>Auto-Generated Message On: " + $date + ".</h5>"
$body += "</font>"

Send-MailMessage -smtpServer $RelayMailServer -from $FromAddress -to $user.Email -subject $Subject -BodyAsHtml  -body $body

}
if ($ReportToAdmin -eq $true)
{
#Add it to admin Report list
$UserList_AboutToExpire += $user.name + "  <font color=blue>(" + $user.LogonName + "</font>) password is about to expire and has " + $DaysLeftTillExpire + " day(s) left</font>. <font color=Green> <br>OU Container: " + $user.DN + "</font> <br><br>"
}
}
}
} # End foreach ($user in $users)

if ($ReportToAdmin -eq $true)
{
If ($UserList_AboutToExpire -eq $null)  {$UserList_AboutToExpire = "No Users to Report"}
If ($UserList_AboutToExpireNoEmail -eq $null){ $UserList_AboutToExpireNoEmail = "No Users to Report"}
if ($UserList_ExpiredHasEmail -eq $null) {$UserList_ExpiredHasEmail = "No Users to Report"}
if ($UserList_ExpiredNoEmail -eq $null) {$UserList_ExpiredNoEmail = "No Users to Report"}
if ($UsersList_WithNoExpiration -eq $null) {$UsersList_WithNoExpiration = "No Users to Report"}

#Email Report to Admin
$Subject="Password Expiration Status for " + $date + "."
$AdminReport = $font + $Title + $Title_ExpiredNoEmail + $UserList_ExpiredNoEmail + $Title_AboutToExpireNoEmail + $UserList_AboutToExpireNoEmail + $Title_AboutToExpire + $UserList_AboutToExpire + $Title_Expired + $UserList_ExpiredHasEmail + $Title_NoExpireDate + $UsersList_WithNoExpiration + "</font>"
Send-MailMessage -smtpServer $RelayMailServer -from $FromAddress -to $AdminEmailAddress -subject $Subject -BodyAsHtml -body $AdminReport
}



Sample Email to the user.

Sample of Admin Report

Updated on May 1, 2012

Added feature to sort Admin report by First Name, Last Name, or Password Expiration Date.

Updated on June 21, 2012

Minor code revision to fix logic errors, still debugging/testing.

, ,

62 Comments

mRemoteNG – Great connection tool for any Admin

A while back I was introduced to mRemoteNG which is a great tool for the admin that works on several platforms and yet wants a tabular interface to manage all of his various connections and best of all its Free! The product allows you to manage RDP, VNC, SSH and Telnet via Putty to name a few. A very useful tool to keep up with all the servers one may manage on the daily basis as well as their Admin web portals, as well as giving you the option to group like products or application servers together in Folders.

Last but not least if you don’t save passwords in it, you can use it to share connection information to other Admins if needed by a simple export/import process.

The URL to this fine tool is: http://www.mremoteng.org/

I’d highly recommend it to any admin.

Leave a comment

Exchange Powershell Script – Mailbox Size Daily Report

One of the things I like to monitor on a daily basis is mailbox sizes.  Quota’s or no, it helps you figure out who your big storage crunchers are, and can be used as a education tool for management to better understand just how much storage is being used and where when it come to exchange.

I wrote this script when I 1st got into using Powershell and I’ve no doubt there are tools to make it prettier but in the end this is small and very functional.

#Print the date to the email

date > C:ScriptsMailboxsize1.txt

#Put in some line returns for a cleaner look

echo "`n`n" >> C:ScriptsMailboxsize1.txt

#Report the size of each mailbox on the exchange server in GB

Get-MailboxStatistics -server exchccr | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},Itemcount >> C:ScriptsMailboxsize1.txt

#Email out results

$date = get-date

$content = get-content C:ScriptsMailboxsize1.txt

$body = $content[1]

$i=2;do {$body=$body + $content[$i] + "`n";$i+=1} While ($content[$i] -ne $NULL);

Send-MailMessage -To users@mydomain.com -From ExchangeServer@mydomain.com -Subject "User Exchange Mailbox Sizes for $date" -Body $body -SmtpServer relayserver.mydomain.com

The results look something like this

Wednesday, October 12, 2011 8:00:04 AM

DisplayName                         TotalItemSize(MB)                 ItemCount
-----------                         -----------------                 ---------
User1                                           12109                     92101
User2                                           11259                    141870
User3                                            9812                    128396

etc

Again just some useful information you might want to report on.

, , , , ,

Leave a comment