Wednesday, August 14, 2013

Password Expiry Notification - Powershell Script

Here's a powershell script to send out email to end user to remind them of password expiry.

Feel free to use it. It's not the best method but it gets the work done for me. If you make it better please post it back so it can help other users.




# ======================================

# = Password Expiry Email Notification =

# ======================================

# Created: [10/10/2013]

# By ijaved
$smtpSrv = "smtp.server.com" #Name of your exchange server.
$emailDomain = "@server.com" #Your email domain
$emailUser = "helpdesk" #Needs this to authenticate before sending email.
$emailPass = "HelpDeskPwd" #Pass for above user.
$emailFrom = helpdesk@server.com #Sender Email Address
$adminEmail = alerts@server.com #CC admin on email sent to user.
$owaUrl = "https://owa.server.com/owa" #OWA URL needed for email msg
$groupName = "RemoteUsers" #Name of security group where user will be picked up from.




#Function Mail Users
 
 
Function mail {
$smtpserver = $smtpSrv
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = $True
$smtp.Credentials = New-Object System.Net.NetworkCredential($emailUser, $emailPass);
$msg.From = $emailFrom
$msg.To.Add(”$email”)
$msg.CC.Add(”$adminEmail”)
$msg.Subject = “Password Expiry Notice!”
$msg.Body = “Hi "+ $fullName +",





 
 
You have $calExpire days left to change your password. Your password will expire on $formatDate.




You can either do it by pressing <CTRL><ALT><DELETE> and then clicking Change Password button or from OWA.

To change it from OWA please follow the below steps :-
 
 
1. Open any Web browser and type $owaUrl in the address bar.




2. Log in using your credentials.

3. Once you are logged in, click on Options, located at the top right hand corner of OWA.

4. Drop down menu will display multiple option. Click on Change Your Password.

5. Enter your former password as well as your new password, and then click on Save.

6. Outlook Web Access will tell you that your password has been successfully changed. Click on OK to log in with your new password.

Best Regards,

HelpDesk"
 
 

$smtp.Send($msg)



}
 
#End Function Mail
 
 




#Users in an array for testing. Add multiple like this "test","test2"

#$users = "jiqbal"
 
 




#Users from domain group
 
 
$pickUser = net group $groupName /domain | out-string

$users = (($pickUser -split "(-{79})|(The command completed successfully.)")[2]) -split "\s+"




#Loop through $users and get each user and run.
 
 
foreach ($user in $users)



{
 
#Check if $user is not empty
 
 
If (!$user){Continue}

Else {



#Execute net user command with username
 
 
$result = net user $user /domain



#Get Firstname of user by selecting string with "Full Name"
 
 
$fName = $result | select-string "Full Name"



#Split at space and drop empty spaces with where-object (where object is not equal to space) collect word 4 & 5 (Firstname & Lastname)
 
 
$filternames = $fName.tostring().split("") | where-object {$_ -ne ""}



#Pick Names from the array 2 & 3
 
 
$name = $filternames[2,3]



#Join the two together
 
 
$fullName = [string]::Join(" ", $name)




#Creating email by adding Firstname.Lastname
 
 
$email = [string]::Join(".", $name) + $emailDomain




#Get password expiry date by searching "Password expires"
 
 
$pwdexpires = $result | select-string "Password expires"




#Split at space and collect array 2 which is the password expiry date
 
 
$formatDate = $pwdexpires.tostring().split(" ") | where-object{$_ -ne ""} ; $formatDate = $formatDate[2]




#If password never expired is selected then you will get error. Skip the user by using if statement
 
 
If ($formatDate -eq "Never"){Write-Host -f red "Skipping $user : Password never expires selected."; Continue}
Else{



#Changing format for expireDate and assigning todays date.
 
 
$expiryDate = Get-Date -Date $formatDate; $today = Get-Date




#Calculate days left to reset by - expiry date with current date. (expiry date will be in future)
 
 
$calExpire = ($expiryDate - $today).days



}
 
#Notify admin about expiry date if its less than 14
 
 
If ($calExpire -le 14){
Write-Host "$fullName has $calExpire days left to change his password. His password will expire on $formatDate."


}
 
#If expiry date is equal to 7 / 3 / 1 then go ahead and send email notification to user.
 
 
If ($calExpire -le 7){mail}
ElseIf ($calExpire -eq 4){mail}
ElseIf ($calExpire -eq 3){mail}
ElseIf ($calExpire -eq 2){mail}
ElseIf ($calExpire -eq 1){mail}
Else {Write-Host -f green "$fullName has $calExpire days left"}



}

}
 


Friday, August 9, 2013

Exchange 2010 - Deny User from distribution list to send mails to other distribution list.

This probably sounds crazy but I was asked to do this.

Basically they wanted to stop a users to send emails to all distribution list. Usually used when terminating a user or if the user is being retarded and sending personal emails to all DL's. Whatever it might be I just had to come up with a script to do it to all over 150 DL. I wasn't going to do it one by one from EMC so I made a cmdlet.

Below is the powershell script for exchange 2010 probably works on 2013 as well.

Make a DL called "Denied Users" and add users or user to that DL if you want to block him from sending emails to DL. Please note that this script will only add the Denied User DL in block list once. So if you create a new DL after running this script. Then that DL will not have Denied users in rejected user and hence you will have to re-run the script.

$temp = Get-DistributionGroup -ResultSize Unlimited

foreach($group in $temp)



{
 
Set-DistributionGroup -Identity $group -RejectMessagesFromDLMembers "Denied Users"



}
 
#Remove the above setting incase they change their mind.

#Set-DistributionGroup -Identity $group -RejectMessagesFromDLMembers $null
 
 
 

Monday, January 16, 2012

Outlook 2010 forward emails after specific time.

Source: http://danfolkes.com/2011/02/18/outlook-rule-only-at-specific-times/

I wanted to create a forward so that helpdesk email gets forwarded to my phone on my personal email. Setting up helpdesk email was the easy way but it gets 20+ emails every hour during work time. After work hours its pretty much quite. So for those times I wanted the rule.

Rules which needs to be created :-

Quoted from the post below :-

"
The Rule that will check email header* for UTC times. Make sure it’s assigned to the FWD category. And then FWD it:

Apply this rule after the message arrives
with '2011 23:' or '2012 18:,2012 19:.....2012 11:' in the message header
    and assigned to 'FWD' category
forward it to 'email@example.com'
"

Seach for this string in header.

2012 18:,2012 19:,2012 20:,2012 21:,2012 22:,2012 23:,2012 24:,2012 01:,2012 02:,2012 03:,2012 04:,2012 05:,2012 06:,2012 07:,2012 08:,2012 09:,2012 10:,2012 11:

Friday, January 13, 2012

DPM 2010 - Script to export all recoverable item to drive

Ok so I finished writing my script for exporting recovery data to f: drive (local to DPM 2010 server) for all the servers (DPM 2010 Agents) I have 4 of them.
If any of you had the pleasure of doing this through GUI knows how painful it is... I fortunately was very lucky to be assigned to export (recover to network folder) 16 datasources from 4 different servers. After doing this for couple of days I started looking at cmdlets and found some scripts and hints on how to do this. and then...
This scripts loops through all the servers and all the datasource protected and recovers them to f: drive then it 7z the files and put in 7z folder it also date stamps folders and 7z files. You have to download 7za and place it in system32 folder in order for it to 7z the folders.

I am posting this script to that it might come handy to someone else out there.

I use this in production environment and it works fine but doesn’t mean it might work for you. So standard disclaimer use it at your own risk! ( I did not write some of the code and copied it from other user posts from this forum. Hopefully they won’t mind). You are free to modify and use the script.

It recovers SQL, System Protection and Exchange 2010. Please note I only export exchange recovery on 15th of every month you can change that. Search for “#Only run Exchange Recovery on 15th of every month. Otherwise Skip” and change the days below that.

# ====================================
# = DPM 2010 Recover to Drive looped =
# = for all servers and datasource.  =
# ====================================
# Created: [01/12/12]
# By EvilWasp

#0 Time Stamp folders
$date = get-date
$TimeStamp = $date.ToShortDateString()
#Replace / as folder name cannot contain it.
$time = $TimeStamp.Replace("/", "-") 
 
#1 You have to modify the below varibles to make it work for you.
#Below varibles
$DPMServerName = "Krait"
$DestinationLocation = "F:\Recovered\$time"
$Destination7z = "F:\7z\$time"
 
#2 Import DPM Shell if its not loaded.
If((Get-PSSnapIn -Name "Microsoft.DataProtectionManager.PowerShell" -ErrorAction SilentlyContinue) -eq $null)
    {
  Add-PSSnapIn "Microsoft.DataProtectionManager.PowerShell"
  Start-Sleep 5
    }

#3 Get list of DPM Agents - Protected Group
$pg = Get-ProtectionGroup -DPMServerName $DPMServerName
#Count how many servers!
$pgc = $pg.count

#4 Start Function Recover it needs $i from $pg.
Function Recover ($i)
{
  #if $i is not null then do the loop.
  If ($i -ne $null) 
  {
    $dsc = $ds.count #Counting how many datasource is available in array
    #Loop through all the servers with ForLoop
    For ($d=0; $d -le $dsc; $d++) #looping datasource for each servers
    {
    $dsn = $ds[$d]
    #8 If & ElseIf Statments to find the write command for each recovery.
    #Three different types -SQL, -SystemProtectionDataSource and -E14datasource for exchange 2010 (Use -Exchange) for older versions. 
    #There's -FileSystem as well which I havent used.
    #-like is used with wildcard(*) to accomodate different versions of SQL i.e 2005, 2008 extra.
        
        #find SQL server in each server
        If ($dsn.Type.Name -like "SQL Server*") 
            {
            #Recovery Options - Where to place recovered files - for SQL
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -SQL -RecoveryType restore
            }
        #find System Protection server
        ElseIf ($dsn.Type.Name -like "System Protection*") 
            {
            #Recovery Options - Where to place recovered files - for System Protection
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -SystemProtectionDataSource -RecoveryType restore
            }
        #find Exchange server
        ElseIf ($dsn.Type.Name -like "Exchange Mailbox Database*") 
            {
            #Only run Exchange Recovery on 15th of every month. Otherwise Skip.
            If ($date.Day -eq 15) 
                {
            #Recovery Options - Where to place recovered files - for Exchange 2010
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -E14datasource -ExchangeOperationType NoOperation -RecoveryType restore
                }
                #If its not the 15th of month then skip
                Else
                {
                Continue
                }
            }
        #If $dsn.Type.Name is nothing/null skip
        Else
         {
         Continue
         }
        #Sort by latest on top Recovery Points.
        $recoveryPoints = @(Get-RecoveryPoint -datasource $dsn | sort -property RepresentedPointInTime -Descending)
            If ($recoveryPoints.Length -eq 0)
                {
                 Write-Host "No recovery point available for" $dsn.Name -ForeGroundColor Yellow
                 }
            Else
                {
        #Select the latest recovery point found on Array [0]
        $latestRecoveryPoint = $RecoveryPoints[0]
        #Recovering
        Write-Host "Recovering" $dsn.Name
        #Run Recovery Job
        $recoveryJob = Recover-RecoverableItem -RecoverableItem $latestRecoveryPoint -RecoveryOption $rop -JobStateChangedEventHandler $jobStateChangeHandler
                }
        #If it failed!
        If(!$recoveryJob)
            {
        Write-Host "Failure on invoking Recover-RecoverableItem" -ForeGroundColor Red
        Continue
            }        
        #Wait till the recovery job completes
        while (! $recoveryJob.hasCompleted )
        { 
        # Show a progress bar
        Write-Host "." -NoNewLine
        Start-Sleep 5
        }
        if($recoveryJob.Status -ne "Succeeded")
        {
        Write-Host "Recovery failed" -ForeGroundColor Red
        }
        else
        {
        Write-Host "Recovery successful" -ForeGroundColor Green
        }
    
    }
  }    
}
#End Function

#5 Count Servers in $pg array
for ($i=0; $i -le $pgc; $i++)
{
#Selecting server and displaying datasource
$ds = Get-Datasource $pg[$i] 
#Call Recover function with $i (server) from #5
Recover $i
}

#6 Once all of recovery is exported 7z these.
cd\ #Ensure its on root
cd $DestinationLocation
$dir = pwd
If ($dir.path -eq  $DestinationLocation)
    {
#7 "&" is required before calling external file.
#Call 7za.exe to compress the whole folder. 7za command line tool needs to be downloaded and placed in system32 folder b4 hand
Write-host "Starting compressiong phase. At $date ....."
Write-host "Compressing Recovered files from DPM Server. This will take time!" -ForeGroundColor Green
& 7za a -t7z "$Destination7z DPM.7z" * 
Write-host "Compression done At $date"    
    }
Else 
    {
Write-host "Something went wrong. You have to run 7z manually!"  -ForeGroundColor Red
    }
#All done exit
Exit
 
 
You can download the ps1 version from Google Docs here's the link.