{"id":954,"date":"2020-02-18T12:40:56","date_gmt":"2020-02-18T12:40:56","guid":{"rendered":"http:\/\/ihni.uk\/?p=954"},"modified":"2020-02-18T12:40:56","modified_gmt":"2020-02-18T12:40:56","slug":"versasec-email-expiring-smart-card-users","status":"publish","type":"post","link":"https:\/\/ihni.uk\/?p=954","title":{"rendered":"Versasec: Email Expiring Smart Card Users"},"content":{"rendered":"<p>This script will read from a CSV and\u00a0will email users who\u2019s smart card logon Certificates are going to expire with-in the next 30 days.<\/p>\n<p>It will give them a stock email with instructions on how to renew their certificate.<\/p>\n<p>It will also email the chosen administrators to inform them as to\u00a0who has been emailed.<\/p>\n<p><!--more--><\/p>\n<p><span id=\"more-964\"><\/span>There is one large caveat with this script, in that the input needs to created manually.<\/p>\n<p>The smart card system that this was designed to work along side had a system to do this very thing, but not in as much detail or have the same function.<\/p>\n<p>Unfortunately it\u00a0stored all users in an encrypted flat file database format, which meant that I was unable to retrieve the information from the application using the script via a SQL query or SQL Dump.<\/p>\n<p>[CC lang=\u2019powershell\u2019]<\/p>\n<p>###################################################################################<br \/>\n#<br \/>\n# Script to Email Users whos smart card certificates are going to expire soon.<br \/>\n#<br \/>\n# 2018\/Jan\/22<br \/>\n#<br \/>\n###################################################################################<br \/>\nPush-Location (Split-Path -path $MyInvocation.MyCommand.Definition -Parent)<br \/>\n$Date = Get-Date -Format dd-MM-yy<br \/>\n$CSV = \u2018.\\SCUsersExpiringNext30days.csv\u2019<br \/>\n$smtpserver = \u2018YOUR-SMTP-SERVER\u2019<\/p>\n<p>#V Validate CSV and email accordingly.<br \/>\n$CSVStatus = $null<br \/>\n$CSVCheckExist = Test-Path $CSV<br \/>\nIf($CSVCheckExist -eq $true){<br \/>\n$CSVStatus = \u201cCSV Exists\u201d<br \/>\nWrite-Host \u201cCSV Exists!\u201d -ForegroundColor Green -BackgroundColor DarkGreen<br \/>\n$lastmodifieddate = (Get-Item $CSV).LastWriteTime;<br \/>\n$csvlastupdate = (New-TimeSpan -start $lastmodifieddate -end $date).days<br \/>\nWrite-Host \u201c$CSVLastUpdate days since modified\u201d -ForegroundColor Green -BackgroundColor DarkGreen<br \/>\nIf($csvlastupdate -gt 7){<br \/>\n$CSVStatus = \u201cCSV Exists; but is over 7 days old!\u201d<br \/>\nWrite-host $CSVStatus -ForegroundColor Yellow -BackgroundColor DarkYellow<br \/>\n$emailto = \u2018YOUREMAIL@YOURDOMAIN.COM\u2019<br \/>\n$subject = \u201cURGENT! Smart Card Certificate Expiry CSV More than 7 days Old!\u201d<br \/>\n$body = Get-Content .\\emails\\GT7.htm -raw<br \/>\nSend-MailMessage -SmtpServer $smtpserver -from $emailfrom -to $emailto -Subject $subject -body $body -bodyashtml -Priority high -Encoding $encoding}<br \/>\nElse{<br \/>\n$CSVStatus = \u201cCSV Less than7 days since modified! Running Script!\u201d<br \/>\nWrite-Host $CSVStatus -ForegroundColor Green -BackgroundColor DarkGreen}<br \/>\n}<br \/>\nElse{<br \/>\n$CSVStatus = \u201cCSV Does Not Exist!\u201d<br \/>\nWrite-Host $CSVStatus -ForegroundColor Red -BackgroundColor Darkred<br \/>\n$emailto = \u2018YOUREMAIL@YOURDOMAIN.COM\u2019<br \/>\n$subject = \u201cURGENT! Smart Card Certificate Expiry CSV DOES NOT EXIXT!\u201d<br \/>\n$body = Get-Content .\\emails\\NoCSV.htm -raw<br \/>\nSend-MailMessage -SmtpServer $smtpserver -from $emailfrom -to $emailto -Subject $subject -body $body -bodyashtml -Priority high -Encoding $encoding<br \/>\nExit<\/p>\n<p>}<\/p>\n<p>function Get-Expirers($upper, $lower){<br \/>\n#$lower = 1<br \/>\n#$upper = 7<br \/>\n$scexpires = Import-Csv $CSV<br \/>\n$emails = @()<br \/>\n$scexpires | %{<br \/>\n$ID = $_.(\u201cID\u201d)<br \/>\n$IssuedTo = $_.(\u201cIssued To\u201d)<br \/>\n$IssuedTo = $IssuedTo -replace \u201c.*CN=\u201d, \u201c\u201d #removes clutter in the \u2018reverse distinguished name\u2019 SMARTCARD APPLICATION provides<br \/>\n$name = $issuedTo<br \/>\n$issuedTo = $IssuedTo -replace \u201d \u201c, \u201c\u201d\u00a0\u00a0\u00a0\u00a0 #removes space for AD search<br \/>\n$issuedTo = $issuedTo -replace \u201c\u2018\u201d, \u201c\u201d\u00a0\u00a0\u00a0\u00a0 #removes pesky apostophies from names.<br \/>\n$Serial = $_.(\u201cSerial Number\u201d)<br \/>\n$ValidTo = $_.(\u201cValid To\u201d)<br \/>\n$ExpiryDate = $ValidTo<br \/>\n$ValidFrom = $_.(\u201cValid From\u201d)<br \/>\n$Template = $_.(\u201cTemplate\u201d)<br \/>\n$Adcheck=Get-ADUser -LDAPFilter \u201c(SAMAccountname=$issuedto)\u201d<br \/>\nIf($adcheck -eq $null){<br \/>\n$issuedto | SC .\\output\\UsersNotInAD-$date.txt}<br \/>\nElse{<br \/>\n$issuedto = $IssuedTo | Where-Object {$validto -as [datetime] -lt (Get-Date).AddDays($upper) -and $validto -as [datetime] -gt (Get-Date).AddDays($lower)} | Get-ADUser -Properties mail # Get Emails for all users due to expire in the next X days<br \/>\n$validto = $validto |\u00a0\u00a0 Where-Object {$validto -as [datetime] -lt (Get-Date).AddDays($upper) -and $validto -as [datetime] -gt (Get-Date).AddDays($lower)}<br \/>\n$issuedToEmail = $issuedto.mail<br \/>\n$emails += $issuedtoEmail #+ $ValidTo<br \/>\n$emails | SC \u201c.\\output\\Expiring in $lower days.txt\u201d<br \/>\n####################################################<br \/>\n#Send some Emails<br \/>\n$today = Get-Date -Format \u201cMMM d, yyyy HH:mm:ss\u201d<br \/>\n$daystoexpire = (New-TimeSpan -start $today -end $ExpiryDate).days<br \/>\n$messagedays = $daystoexpire<br \/>\nIf($messagedays -gt \u201c1\u201d){<br \/>\n$messagedays = \u201cin \u201d + \u201c$daystoexpire\u201d + \u201d days\u201d}<br \/>\nElse{<br \/>\n$messagedays = \u2018today\u2019}<br \/>\n$smtpserver = \u2018YOURSMTPSERVER\u2019<br \/>\n$emailFrom = \u2018SmartCardExpiry@YOURDOMAIN.COM\u2019<br \/>\n$emailTo = $issuedToEmail<br \/>\n$subject = \u201cAction Required \u2013 Your Smartcard certificate is due to expire $messagedays\u201d<br \/>\n$body = Get-Content .\\EMAILS\\smartcard_expiry_message.htm -Raw<br \/>\n$body = $body.replace(\u2018$name\u2019,$name)<br \/>\n$body = $body.replace(\u2018$messagedays\u2019,$messagedays)<br \/>\n$encoding = [System.Text.Encoding]::UTF8<br \/>\nIf ($emailto -eq $null){<br \/>\n#Continue<br \/>\n}<br \/>\nElse{<br \/>\nSend-MailMessage -SmtpServer $smtpserver -from $emailfrom -to $emailto -Subject $subject -body $body -bodyashtml -Priority high -Encoding $encoding<\/p>\n<p>}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>Get-Expirers -lower 0 -upper 1<br \/>\nGet-Expirers -lower 1 -upper 7<br \/>\nGet-Expirers -lower 7 -upper 14<br \/>\nGet-Expirers -lower 14 -upper 21<br \/>\nGet-Expirers -lower 21 -upper 28<br \/>\nGet-Expirers -lower 28 -upper 31<\/p>\n<p># Send Report email to Tech teams<br \/>\n$xtoday = Get-Content \u201c.\\output\\Expiring in 0 days.txt\u201d<br \/>\n$xTomorrow = Get-Content \u201c.\\output\\Expiring in 1 days.txt\u201d<br \/>\n$x7Days = Get-Content \u201c.\\output\\Expiring in 7 days.txt\u201d<br \/>\n$x14days = Get-Content \u201c.\\output\\Expiring in 14 days.txt\u201d<br \/>\n$x21days = Get-Content \u201c.\\output\\Expiring in 21 days.txt\u201d<br \/>\n$x28days =\u00a0 Get-Content \u201c.\\output\\Expiring in 28 days.txt\u201d<br \/>\n$notInAD = Get-Content \u201c.\\output\\UsersNotInAD-$date.txt\u201d<\/p>\n<p>$emailto = \u2018YOUREMAIL@YOURDOMAIN.COM\u2019<br \/>\n$emailFrom = \u2018SmartCardExpiry@YOURDOMAIN.COM\u2019<br \/>\n$encoding = [System.Text.Encoding]::UTF8<br \/>\n$subject = \u201cSmart Card Certificate Expiry Emails Sent Today\u201d<\/p>\n<p>$xbody = Get-Content .\\emails\\Emailreport.htm -raw<\/p>\n<p>If($xtoday -eq $null){$xtoday = \u2018No users\u2019}else{$xtoday = $xtoday | Out-String}<br \/>\nIf($xTomorrow -eq $null){$xTomorrow = \u2018No users\u2019}else{$xtomorrow = $xtomorrow | Out-String}<br \/>\nIf($x7Days -eq $null){$x7Days = \u2018No users\u2019}else{$x7days = $x7days | Out-String}<br \/>\nIf($x14days -eq $null){$x14days = \u2018No users\u2019}else{$x14days = $x14days | Out-String}<br \/>\nIf($x21days -eq $null){$x21days = \u2018No users\u2019}else{$x21days = $x21days | Out-String}<br \/>\nIf($x28days -eq $null){$x28days = \u2018No users\u2019}else{$x28days = $x28days | Out-String}<br \/>\nIf($notinAD -eq $null){$notinad = \u2018No users\u2019}else{$notinad = $notinad | Out-String}<\/p>\n<p>$xbody = $xbody -replace \u201c#Date\u201d, \u201c$Date\u201d<br \/>\n$xbody = $xbody -replace \u201c#xtoday\u201d,\u201d$xToday\u201d<br \/>\n$xbody = $xbody -replace \u201c#xTomorrow\u201d,\u201d$xTomorrow\u201d<br \/>\n$xbody = $xbody -replace \u201c#x7Days\u201d,\u201d$x7Days\u201d<br \/>\n$xbody = $xbody -replace \u201c#x14days\u201d,\u201d$x14days\u201d<br \/>\n$xbody = $xbody -replace \u201c#x21days\u201d,\u201d$x21days\u201d<br \/>\n$xbody = $xbody -replace \u201c#x28days\u201d,\u201d$x28days\u201d<br \/>\n$xbody = $xbody -replace \u201c@interservefls.gse.gov.uk\u201d,\u201d&lt;br&gt;&lt;br&gt;\u201d<br \/>\n$xbody = $xbody -replace \u201c#CSVStatus\u201d, \u201c$CSVStatus\u201d<br \/>\n$xbody = $xbody -replace \u201c#NotInAD\u201d, \u201c$NotinAD\u201d<\/p>\n<p>Send-MailMessage -SmtpServer $smtpserver -from $emailfrom -to $emailto -Subject $subject -body $xbody -bodyashtml -Priority high -Encoding $encoding -verbose<\/p>\n<p>[\/CC]<\/p>\n<p>The CSV should be laid out in the following format, you can of course modify the script and CSV to suit your needs.<\/p>\n<p>[cc lang=\u2019csv\u2019]<\/p>\n<p>ID,Issued to,Serial Number,Valid to,Valid from,Template<br \/>\n1234,\u201dDC=UK, DC=yourorg, DC=yourco, DC=DOM, OU=HQ, OU=Users, CN=Joe Bloggs\u201d,7D00006638281FF48060C3F02B000100006638,\u201dApr 28, 2018 13:34:06\u2033,\u201dApr 28, 2017 13:34:06\u2033, User Card<\/p>\n<p>[\/CC]<\/p>\n<p>&nbsp;<\/p>\n<p>Email Templates look like the following:<\/p>\n<p>Greater than 7 Day old CSV file.<\/p>\n<p>[cc lang=\u2019html\u2019]<\/p>\n<p>&lt;!\u2013 Message template used by PowerShell script to mail admin accounts that the CSV has not been updated. \u2013&gt;<br \/>\n&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;style type=\u2019text\/css\u2019&gt;<br \/>\n&lt;!\u2013<br \/>\n#container {<br \/>\ncolor:#0072C6;<br \/>\nfont-family:\u2019Calibri\u2019,\u2019Arial\u2019,\u2019Verdana\u2019;<br \/>\nmargin-left:auto;<br \/>\nmargin-right:auto;<br \/>\ntext-align:justify;<br \/>\n}<br \/>\n\u2013&gt;<br \/>\n&lt;\/style&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;div id=\u2019container\u2019&gt;<br \/>\n&lt;H3&gt;LADS!&lt;\/h3&gt;<br \/>\n&lt;p&gt;<br \/>\n&lt;h3 style=\u201dcolor:red;\u201d&gt;The CSV for the Smart Card Certificat Expirations IS OLD!!&lt;\/h3&gt;<br \/>\n&lt;h3&gt;Please go and make sure that this file is updated!&lt;\/h3&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n<p>[\/CC]<\/p>\n<p>No CSV File present.<\/p>\n<p>[cc lang=\u2019html\u2019]<\/p>\n<p>&lt;!\u2013 Message template used by PowerShell script to mail admin accounts that the CSV does not exist. \u2013&gt;<br \/>\n&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;style type=\u2019text\/css\u2019&gt;<br \/>\n&lt;!\u2013<br \/>\n#container {<br \/>\ncolor:#0072C6;<br \/>\nfont-family:\u2019Calibri\u2019,\u2019Arial\u2019,\u2019Verdana\u2019;<br \/>\nmargin-left:auto;<br \/>\nmargin-right:auto;<br \/>\ntext-align:justify;<br \/>\n}<br \/>\n\u2013&gt;<br \/>\n&lt;\/style&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;div id=\u2019container\u2019&gt;<br \/>\n&lt;p&gt;LADS!&lt;\/p&gt;<br \/>\n&lt;p&gt;<br \/>\n&lt;h3 style=\u201dcolor:red;\u201d&gt;The CSV for the Smart Card Certificat Expirations does not exist!!&lt;\/h3&gt;<br \/>\n&lt;h3&gt;Please go and make sure that this file is created!&lt;\/h3&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n<p>[\/CC]<\/p>\n<p>Email Report:<\/p>\n<p>[cc lang=\u2019html\u2019]<\/p>\n<p>&lt;!\u2013 Message template used by PowerShell script to mail admin accounts that the CSV does not exist. \u2013&gt;<br \/>\n&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;style type=\u2019text\/css\u2019&gt;<br \/>\n&lt;!\u2013<br \/>\n#container {<br \/>\ncolor:#0072C6;<br \/>\nfont-family:\u2019Calibri\u2019,\u2019Arial\u2019,\u2019Verdana\u2019;<br \/>\nmargin-left:auto;<br \/>\nmargin-right:auto;<br \/>\ntext-align:justify;<br \/>\n}<br \/>\n\u2013&gt;<br \/>\n&lt;\/style&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;div id=\u2019container\u2019&gt;<br \/>\n&lt;p&gt;Hello Support Teams,&lt;\/p&gt;<br \/>\n&lt;p&gt;<br \/>\n&lt;h3&gt;#CSVStatus&lt;\/h3&gt;<br \/>\n&lt;h3&gt;The Following users were emailed today #Date for Smart Card Certificate Expirations.&lt;\/h3&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;style type=\u201dtext\/css\u201d&gt;<br \/>\n.tg\u00a0 {border-collapse:collapse;border-spacing:0;border-color:#999;}<br \/>\n.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#999;color:#444;background-color:#F7FDFA;}<br \/>\n.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#999;color:#fff;background-color:#26ADE4;}<br \/>\n.tg .tg-6dj7{font-weight:bold;font-size:small;background-color:#34cdf9;color:#343434;text-align:center;vertical-align:top}<br \/>\n.tg .tg-y5sk{font-size:x-small;vertical-align:top}<br \/>\n&lt;\/style&gt;<br \/>\n&lt;table class=\u201dtg\u201d&gt;<br \/>\n&lt;tr&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;Today&lt;\/th&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;Tomorrow&lt;\/th&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;7Days&lt;\/th&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;14 Days&lt;\/th&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;21 Days&lt;\/th&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;28 days&lt;\/th&gt;<br \/>\n&lt;\/tr&gt;<br \/>\n&lt;tr&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#xToday&lt;\/td&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#xTomorrow&lt;\/td&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#x7days&lt;\/td&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#x14Days&lt;\/td&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#x21Days&lt;\/td&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#x28Days&lt;\/td&gt;<br \/>\n&lt;\/tr&gt;<br \/>\n&lt;\/table&gt;<br \/>\n&lt;br&gt;<br \/>\n&lt;table&gt;<br \/>\n&lt;table class=\u201dtg\u201d&gt;<br \/>\n&lt;tr&gt;<br \/>\n&lt;th class=\u201dtg-6dj7\u2033&gt;Users not in AD with expiring SC Cert.&lt;\/th&gt;<br \/>\n&lt;\/tr&gt;<br \/>\n&lt;tr&gt;<br \/>\n&lt;td class=\u201dtg-y5sk\u201d&gt;#notInAD&lt;\/td&gt;<br \/>\n&lt;\/tr&gt;<br \/>\n&lt;\/table&gt;<\/p>\n<p>&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n<p>[\/CC]<\/p>\n<p>The Email Message each user will receive starts with the following, instructions will be provided too. The name and messagedays variables will be filled in by the script.<\/p>\n<p>[cc lang=&#8217;html&#8217;]<\/p>\n<p>Dear $name<\/p>\n<h3>Your smartcard certificate will expire $messagedays \u2013 If you do not re-issue the certificate before it expires it will impact your ability to logon<\/h3>\n<h3>PLEASE DO NOT RESPOND TO THIS EMAIL \u2013 THIS IS FOR NOTIFICATION PURPOSES ONLY<\/h3>\n<h3>If you have already reissued your Smart Card Certificate, then you can safely disregard this email.<\/h3>\n<p>[\/CC]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This script will read from a CSV and\u00a0will email users who\u2019s smart card logon Certificates&hellip;<\/p>\n","protected":false},"author":1,"featured_media":988,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10,19,11,13],"tags":[],"class_list":["post-954","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pki","category-powershell","category-scripts","category-versasec"],"jetpack_featured_media_url":"https:\/\/ihni.uk\/wp-content\/uploads\/2020\/02\/Powershell.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/posts\/954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ihni.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=954"}],"version-history":[{"count":0,"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/posts\/954\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ihni.uk\/index.php?rest_route=\/wp\/v2\/media\/988"}],"wp:attachment":[{"href":"https:\/\/ihni.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ihni.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ihni.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}