Tuesday, 25 September 2018

Send daily HTML email with outstanding Hyper-V checkpoints with encrypted password information

 

 

Here’s a script I’ve written that can be added as a scheduled task on the SCVMM server to send a daily report to selected people containing all the currently outstanding checkpoints on the Hyper-V hosts.  This is done without having to store any plain text passwords (they are stored but in an encrypted format).  It formats the email as HTML so that it looks a bit prettier.  I could have made the HTML fancier but I wanted to keep the script simple.

 

 

$Header = @"

       <style>

       TABLE {font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; border: 1px solid #FFFFFF; background-color: #FFFFFF; width: 750px; height: 100px; text-align: center; border-collapse: collapse;}

       TH {background: #FF0000; border-bottom: 5px solid #FFFFFF; }

       TD { border: 1px solid #FFFFFF;}

       tr:nth-child(odd) {background: #D0CFD1; padding: 3px 2px; }

       </style>

"@

 

$Transpath = "C:\temp\logs\snapshot_report.log"

$DateTime = (Get-Date).ToString('dd/MM/yy hh:mm:ss')

$password = cat C:\scripts\securestring.txt | ConvertTo-SecureString

$mycred = New-Object System.Management.Automation.PSCredential ("username",$password)

$Date = Get-Date -Format "dd-MM-yyyy"

$Subject = "Daily Snapshot Report from $env:computername for $Date"

$Greeting = "Good morning, please find below the daily snapshot report.  For any queries on this report please contact Tom K `(info`@cloudwyse.co.uk`)"

$ReportText = Get-SCVirtualMachine | Get-VMCheckpoint | Select VM,Name,Description,AddedTime | ConvertTo-HTML -Head $Header -Body "$Greeting $_ " | Out-String

$Recipients = 'email1@cloudwyse.co.uk','email2@cloudwyse.co.uk','email3@cloudwyse.co.uk'

 

Start-Transcript -Path "$transpath" -Append

Write-Host "Started running script on $env:computername at $DateTime"

 

Send-MailMessage `

       -SmtpServer smtpserver.contoso.com `

       -Credential $mycred `

       -From 'reports@cloudwyse.co.uk' `

       -To $Recipients `

       -Subject $Subject `

       -Body $ReportText -BodyAsHtml `

       -Port 587 -UseSsl

 

Write-Host "Finished running script on $env:computername at $DateTime"

Stop-Transcript

 

 

Follow the instructions here to create the securestring.txt

 

 

Search through previous powershell commands with grep

 

 

It can be really difficult trying to remember that command you used a few weeks ago in Powershell.  Here’s an easy way to search through your previous commands to find the right one and jog your memory. First, run

 

 

(Get-PSReadlineOption).HistorySavePath

C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

 

 

Then you can cat the output to look for the command

 

 

cat C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

 

 

Or just open it in notepad

 

 

notepad C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

 

 

If you want to search for a specific command within your history you can use findstr as follows

 

 

cat C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt | findstr -i get-azureadgr

 

 

Or if you’re more comfortable with the UNIX/Linux commands like myself you can use grep in Powershell by creating an alias as follows

 

 

new-alias grep findstr

 

 

And search for the command as before, but this time using grep 😊

 

 

cat C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt | grep -i get-azureadgr

 

Monday, 16 July 2018

Confused about deprecated O365 commands?

 

 

I was getting pretty confused with the various options around powershell commands to use with Exchange online.  For example, to add a user to a distribution group in O365, I had come across 4 different commands:

 

 

Add-AzureADGroupMember

Add-AzureRMADGroupMember

Add-DistributionGroupMember

Add-MsolGroupMember

 

 

So after some digging I realised that the *-AzureRM* are powershell cmdlets to modify general Azure resources using the Azure Resource Manager model – read more here (first couple of links are most useful)

 

Furthermore, the current way to manipulate Azure AD is to use the V2 cmdlets:  *-AzureAD* read more here 

 

The older *MSOL* cmdlets have been completely replaced by the *-azureAD* cmdlets.  Although the older cmdlets still work, they have been marked as deprecated so at some point they will stop but that might not be for a while. Read more here.

 

The Add-DistributionGroupMember cmdlet applies to Exchange and Exchange Online.  Given that Microsoft haven’t given any indication that they are likely to remove support for hybrid environments it is likely these will be around for a while.

 

 

 

 

Friday, 13 July 2018

Powershell script for creating an O365 cloud mailbox within a hybrid exchange environment

 

 

I recently wrote this script that creates an O365 mailbox within a hybrid exchange environment, creating all the necessary attributes etc in exchange and AD


Log all output to a local logfile, that is unique each time and won't get overwritten

 

 

Start-Transcript -Path $env:LOCALAPPDATA"\Cloudwyse\Logs\"$(get-date -Format ddMMyy_HHmmss)".log" -NoClobber

 

 

Clear output from the screen to prevent previous command being sent as first name

 

 

Clear-Host

 

 

Prompt user to enter the details of the new account

 

 

$FirstName = Read-Host -Prompt "Carefully type the user`'s First name"

$SecondName = Read-Host -Prompt "Carefully type the user`'s Second name"

 

 

Format the AD fields in the right way

 

 

$UserName = $FirstName.ToLower() + "." + $SecondName.ToLower()

$DisplayName = (Get-Culture).TextInfo.ToTitleCase($FirstName.ToLower() + " " + $SecondName.ToLower())

$ProperFName = (Get-Culture).TextInfo.ToTitleCase($FirstName.ToLower())

$ProperSName = (Get-Culture).TextInfo.ToTitleCase($SecondName.ToLower())

$UPN = $UserName + "@contoso.com"

write-host -ForegroundColor Green "Your User`'s DisplayName is $($DisplayName)"

write-host -ForegroundColor Green "Your User`'s Username is $($UserName)"

 

 

Get credentials for the new user account and the connection to the on-prem exchange server

 

 

$UserCreds = Get-Credential -UserName "DO NOT EDIT THIS FIELD" -Message "Please set the password for the new user"

$ExchangeCreds = Get-Credential -UserName "CONTOSO`\" -Message "Please enter your credentials which are required to connect to CONEXCH01"

write-host -ForegroundColor Green "Your User`'s UPN is $($UPN)"

 

 

Connect to on-prem exchange and create mailbox

 

 

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://CONEXCH01.contoso.com/PowerShell/ -Authentication Kerberos -Credential $ExchangeCreds

Import-PSSession $Session

New-RemoteMailbox -Name $DisplayName -FirstName $ProperFName -LastName $ProperSName -Password $UserCreds.Password -UserPrincipalName $UPN -OnPremisesOrganizationalUnit "contoso.com/CONTOSO Users/Swap"

 

 

Disconnect from exchange and stop logging

 

 

Remove-PSSession $Session

write-host -ForegroundColor Green "The script completed, any errors will appear in the log file"

Stop-Transcript

 

 

 

Thursday, 12 July 2018

Adding Users to O365 Distribution List

 

A script I recently used to add members to an office 365 distribution group using a remote exchange session in a hybrid setup (covered at the end). 

 

$SourceFile = "<path to file>"

Import-CSV $SourceFile | ForEach `

{Add-DistributionGroupMember -Identity "Group Name" -Member $_.UPN

Write-Host -ForegroundColor Green "Processed the record for $($_.UPN)"

}

 

 

CSV file contains UPNs of all users to be added.

 

I also found it useful to see who had permissions to send to this group using

 

 

(Get-DistributionGroup -Identity "Group Name").AcceptMessagesOnlyFrom | ForEach {Get-User -Identity $_}

 

 

To open remote exchange shell:

 

 

$UserCredential = Get-Credential

 

 

A prompt will appear for your login credentials then,

 

 

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection

Import-PSSession $Session