· 6 years ago · May 23, 2019, 09:54 PM
1###script to create and send RSA soft token emails to users
2# Instruction for downlaod RSA but no import in W10
3 param (
4 [switch]$gui = $false
5 )
6
7[reflection.assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
8#Import-Module activedirectory
9
10$myPath = [System.IO.Path]::GetDirectoryName($myInvocation.myCommand.definition)
11
12# Email Parameters
13$nl = [Environment]::NewLine
14$smtpServer = "smtp.fyiblue.com"
15$mailFrom = "BYODMobility@bcbsil.com"
16#$mailfrom = "Null"
17$mailBcc = "chris_souza@bcbsil.com", "ISSecurity@bcbstx.com"
18$mailBccExt = "chris_souza@bcbsil.com", "MobilityServices@bcbsil.com", "ISSecurity@bcbstx.com"
19$mailSubject = "RSA SecurID Soft Token Installation"
20$mailSubjectExt = "RSA SecurID Soft Token Installation (ENCRYPT)"
21$attachment = "$myPath\FirstTimeRSAandVDISetup.docx"
22
23$log = "c:\temp\rsaTokenHelper.log"
24###change these to use Windows auth. then add individual read-only access for SQL users.
25$invDbString = "Server=pwauswshsq37;Database=WILLIS;User=bes;Password=bes1"
26$goodDbString = "Server=pwauswmssq01a;Database=GMC1;User=wireless_inventory;Password=G19ANCwK"
27$gcDbString = "Server=pwauswmssq01a;Database=GC1;User=wireless_inventory;Password=G19ANCwK"
28$gcCidDbString = "Server=pwauswmssq01a;Database=CID-GC1;User=wireless_inventory;Password=G19ANCwK"
29
30$tokenDir = "D:\\Data\\RSA\\tokens"
31$tokenDir2 = "\\mswautelcom01\\tokens"
32$stagingDir = "D:\\Data\\RSA\\rsa"
33$stagingDir2 = "\\mswautelcom01\\rsa"
34
35$flagFile = "$tokenDir\flag.flg"
36
37# Body of Mobility Email, with RSA Import Link
38$gfeHtml = @"
39 <html>
40 <head>
41 <style>
42 h1 {font: 1.5em Helvetica, Verdana, Sans-Serif;}
43 </style>
44 </head>
45 <body>
46 Hi {name},<br><br>
47 Welcome to the HCSC's Bring Your Own Device (BYOD) program! Users who had an RSA Soft Token installed on their corporate BlackBerry devices can install the same functionality on their iOS or Android smartphones.
48 <br><br>juli
49 <a href="http://hcsc.fyiblue.com/computers/hardware/desk/mobile/installation_guide_rsa_secureid_app.pdf">Click here</a> for detailed instructions or follow the steps below <u>on your personal smartphone</u> to install and configure RSA SecurID :
50 <br>
51 <ol><h1>Apple iOS</h1>
52 <li>
53 Launch your mobile devices’ app store and download the RSA SecureID application.<br>
54 <a href="https://itunes.apple.com/us/app/rsa-securid-software-token/id318038618?mt=8&uo=4"><img src="http://media.www1.good.com/images/store_img_itunes.gif"></img></a>
55 </li>
56 <li>
57 Once installed, open the RSA Token email on your BYOD mobile device in Good.<br>
58 </li>
59 <li>
60 Click the link associated with your devices’ operating system. The new RSA application launches.
61 <a href="{iosLink}">Import Token</a>
62 </li>
63 <li>
64 Use the new Tokencode (Passcode) to log into VPN or AnyPlace Web on your PC.
65 </li>
66 </ol>
67 <br>
68 <ol><h1>Android</h1>
69 <li>
70 Launch your mobile devices’ app store and download the RSA SecureID application.<br>
71 <a href="https://play.google.com/store/apps/details?id=com.rsa.securidapp"><img src="http://media.www1.good.com/images/store_img_google.gif"></img></a>
72 </li>
73 <li>
74 Once installed, open the RSA Token email on your BYOD mobile device in Good.<br>
75 </li>
76 <li>
77 Click the link associated with your devices’ operating system. The new RSA application launches.
78 <a href="{droidLink}">Import Token</a>
79 </li>
80 <li>
81 Use the new Tokencode (Passcode) to log into VPN or AnyPlace Web on your PC.
82 </li>
83 </ol>
84 </body>
85 </html>
86"@
87
88# Body of RSA Token Setup Process
89$workHtml = @"
90 <html>
91 <head>
92 <style>
93 h1 {font: 1.5em Helvetica, Verdana, Sans-Serif;}
94 </style>
95 </head>
96 <body>
97 Hi {name},
98 <br><br>
99 Welcome to HCSC Remote Access Management. The steps below will guide you through the softtoken setup process on your mobile device. Do not retain this email as softtokens can change over time.<br><br>
100 <b>Step 1:</b> Note your setup type
101 <ol><li>New to receiving a softtoken</li>
102 <li>Receiving a softtoken due to a new smartphone</li>
103 <li>Received a notification that your softtoken expired and you need to import a new token</li>
104 <li>Laptop users skip to bottom of email</li></ol>
105 <b>Step 2:</b>
106 <h1><b>Apple iOS</b></h1>
107 <ol><li><b><u><font color="blue">Important</font></u></b>: Forward this email to your personal email account that's connected to your phone (i.e. Gmail, Yahoo, AOL email).</li>
108 <li>Launch your mobile device app store and download the RSA SecurID application.<br>
109 <a href="https://itunes.apple.com/us/app/rsa-securid-software-token/id318038618?mt=8"><img src="https://is3-ssl.mzstatic.com/image/thumb/Purple118/v4/6a/b7/b3/6ab7b321-ddc8-d867-301a-2b13dee342ca/mzl.ertgyigo.png/1200x630bb.jpg" height="50" width="50"></img></a></li>
110 <li>Once RSA has been installed, copy and paste the link below and paste into the URL line of the Safari browser:<br>
111 {iosLink}</li>
112 <li>Proceed based on setup type</li>
113 <ol type="a"><li>If you are new to receiving a softtoken, please follow the instructions that will be sent from the IS Fulfillment team explaining how to setup your softtoken PIN.</li>
114 <li>If you requested a softtoken due to a new device, continue to use your existing PIN.</li>
115 <li>If you received a notification stating that your softtoken will be expiring, please follow the instructions that will be sent from the IS Fulfillment team explaining how to remove the expiring token from your smartphone. Your PIN number will remain the same.</li></ol></ol>
116 <h1><b>Android</b></h1>
117 <ol><li><b><u><font color="blue">Important</font></u></b>: Forward this email to your personal email account that's connected to your phone (i.e. Gmail, Yahoo, AOL email).</li>
118 <li>Launch the Google Play Store and download the RSA SecurID application.<br>
119 <a href="https://play.google.com/store/apps/details?id=com.rsa.securidapp"><img src="https://is3-ssl.mzstatic.com/image/thumb/Purple118/v4/6a/b7/b3/6ab7b321-ddc8-d867-301a-2b13dee342ca/mzl.ertgyigo.png/1200x630bb.jpg" height="50" width="50"></img></a></li>
120 <li>Once the RSA application has been installed, click on the RSA Token link below:<br>
121 {droidLink}</li>
122 <li>Proceed based on setup type</li>
123 <ol type="a"><li>If you are new to receiving a softtoken, please follow the instructions that will be sent from the IS Fulfillment team explaining how to setup your softtoken PIN.</li>
124 <li>If you requested a softtoken due to a new device, continue to use your existing PIN.</li>
125 <li>If you received a notification stating that your softtoken will be expiring, please follow the instructions that will be sent from the IS Fulfillment team explaining how to remove the expiring token from your smartphone. Your PIN number will remain the same.</li></ol></ol>
126 <h1><b>HCSC Laptop (Windows)</b></h1>
127 <ol><li>If you have received an HCSC laptop, the RSA softtoken will be installed on your laptop. Please follow the instructions that will be sent from the IS Fulfillment team explaining how to setup your softtoken and set up your PIN.</li></ol>
128 </body>
129 </html>
130"@
131
132# Template for RSA Setup
133$templateHtmlExt = @"
134 <html>
135 <head>
136 <style>
137 h1 {font: 1.5em Helvetica, Verdana, Sans-Serif;}
138 </style>
139 </head>
140 <body>
141 Hi {name},
142 <br><br>
143 Welcome to the HCSC remote access! The below email contains a RSA Soft Token for accessing the HCSC network. The Soft Token can be installed on either an iOS or Android device. To continue, follow the steps below <u>on your personal smartphone</u> to install and configure RSA SecurID :
144 <br>
145 <ol><h1><b>Apple iOS</b></h1>
146 <li>
147 Launch your mobile device app store and download the RSA SecurID application.<br>
148 <a href="https://itunes.apple.com/us/app/rsa-securid-software-token/id318038618?mt=8"><img src="https://is3-ssl.mzstatic.com/image/thumb/Purple118/v4/6a/b7/b3/6ab7b321-ddc8-d867-301a-2b13dee342ca/mzl.ertgyigo.png/1200x630bb.jpg" height="50" width="50"></img></a>
149 </li>
150 <li>
151 Once installed, click the RSA Token link below from your personal email account.<br>
152 </li>
153 <li>
154 Click the link associated with your devices operating system. The new RSA application launches.
155 Import your token by clicking on the link below:<br>
156 {iosLink}
157 </li>
158 <li>
159 Use the new Tokencode (Passcode) to log into VPN or AnyPlace Web on your PC.
160 </li>
161 </ol>
162 <br>
163 <ol><h1><b>Android</b></h1>
164 <li>
165 Launch your mobile device app store and download the RSA SecurID application.<br>
166 <a href="https://play.google.com/store/apps/details?id=com.rsa.securidapp"><img src="https://is3-ssl.mzstatic.com/image/thumb/Purple118/v4/6a/b7/b3/6ab7b321-ddc8-d867-301a-2b13dee342ca/mzl.ertgyigo.png/1200x630bb.jpg" height="50" width="50"></img></a>
167 </li>
168 <li>
169 Once installed, click the RSA Token link below from your personal email account.<br>
170 </li>
171 <li>
172 Click the link associated with your devices operating system. The new RSA application launches.
173 Import your token by clicking on the link below:<br>
174 {droidLink}
175 </li>
176 <li>
177 Use the new Tokencode (Passcode) to log into VPN or AnyPlace Web on your PC.
178 </li>
179 </ol>
180 <br><br>
181 </body>
182 </html>
183"@
184
185###log() - basic logging function
186function log($msg) {
187 $now = Get-Date
188 $msg = "$now - $msg"
189 #$msg | echo >> $log
190 $msg | out-file -append -filepath $log
191 Write-Host $msg
192}
193
194##writeFlag() - create or touch a flag file. the flag modified timestamp will be used to find new/modified files.
195function writeFlag() {
196 New-Item $flagFile -force -ItemType file | Out-Null
197}
198
199function readFlag() {
200 Get-Item $flagFile | select LastWriteTime
201}
202
203###queryDb() - wrapper for sql queries
204###beware, powershell can/will sabatoge you here.
205###queries w/ one result will be flattened to a single object
206function queryDb($dbString, $query) {
207 $db = New-Object System.Data.SqlClient.SqlConnection
208 #$db.ConnectionString = "Server=pwauswshsq37;Database=WILLIS;User=bes;Password=bes1"
209 $db.ConnectionString = $dbString
210 $db.Open()
211 $cmd = New-Object System.Data.SqlClient.SqlCommand
212 $cmd.CommandText = $query
213 #log "sql command: $query"
214 $cmd.Connection = $db
215 #Push-Location
216 $reader = $cmd.ExecuteReader()
217 $result = @()
218 while($reader.Read()) {
219 $row = @()
220 for($i=0;$i -lt $reader.FieldCount;$i++) {
221 $value = $reader.getValue($i)
222 $row += , $value
223 }
224 $result += , $row
225 }
226 $db.Close()
227 #Pop-Location
228 $result
229}
230
231# Method to check if a user account has a token? This could be used to thin out the list of potential tokens
232###isValidToken - returns true if tokenconverter created a valid token string
233function isValidToken($token) {
234 log "Testing token $token"
235 if($token -match "ctfData") {
236 $true
237 } else {
238 log "Invalid token URL $token"
239 $false
240 }
241}
242
243function getDirectoryUser($id) {
244 $user = Get-AdUser -properties mail $id
245 $userDN = Get-AdUser -properties displayName $id
246 $email = $user.mail
247 $dName = $userDN.displayName
248 if ($user -ne $null) {
249 log "Found directory ID $id ($dName)"
250 } else {
251 log "Did not find ID $id in directory"
252 }
253 $user
254}
255
256function isGoodUser($email) {
257 $cleanEmail = $email.replace("'", "''")
258 #$query = "select email_address from gdUserSummary where email_address like '$cleanEmail'"
259 $query = "select email_address from gd_entities where email_address like '$cleanEmail'"
260 $result = queryDb $goodDbString $query
261 if($result.count -gt 0) {
262 log "$email is a GFE user"
263 $true
264 } else {
265 $false
266 }
267}
268
269function isWorkUser($email) {
270 $cleanEmail = $email.replace("'", "''")
271 #$query = "select prov_id from gdDynamicsApplications where prov_id like '$cleanEmail' and application_id = 'com.good.gcs.g3' and activation_date is not NULL"
272 $query = "select distinct prov_id from t_gc_containers where native_display_name in ('Good Work','Work') and prov_id = '$cleanEmail'"
273 $result = queryDb $gcDbString $query
274 $resultCid = queryDb $gcCidDbString $query
275 if($result.count -gt 0 -or $resultCid.count -gt 0) {
276 log "$email is a Good Work user"
277 $true
278 } else {
279 log "$email is not a Good Work user"
280 $false
281 }
282}
283
284function Invoke-RSATokenProcess() {
285 $tokenConverterPath = ".\TokenConverter.exe"
286 $tokens = @(Get-ChildItem $stagingDir -filter "*.sdtid")
287 $tokenCount = $tokens.Count
288 if(!($tokens)) {
289 log "No new tokens found in staging directory"
290 }
291 else {
292 log "Found $tokenCount new tokens"
293 $i = 0
294 $startTime = Get-Date
295 foreach($token in $tokens) {
296 $i += 1
297 $id = $token.name.split('_')[0]
298 $tokenSrcPath = $token.FullName
299 log "Found new token in staging for $id. Looking up."
300 $user = getDirectoryUser $id
301 if(!($user)) {
302 log "No directory user found for $id"
303 }
304 else {
305 $tokenFile = "$($user.mail).sdtid"
306 $tokenDstPath = "$tokenDir\$tokenFile"
307 log "Found directory user $($user.mail). New token path $tokenDstPath"
308 $exists = Get-Item $tokenDstPath -ErrorAction SilentlyContinue
309 if($exists) {
310 $backupTokenPath = "$($tokenDstPath).$(Get-Date -Format yyymmddhhmmss)"
311 log "Backing up existing token to $backupTokenPath"
312 Move-Item $tokenDstPath $backupTokenPath -Force
313 }
314 Move-Item $tokenSrcPath $tokenDstPath
315 Get-Item $tokenDstPath | % {$_.LastWriteTime = Get-Date}
316 log "Processing token $tokenFile"
317 $iosCmd = $tokenConverterPath + " " + $tokenDir + "\" + '"$tokenFile"' + " -mobile"
318 $iosLink = Invoke-Expression -Command $iosCmd
319 $droidLink = createDroidLink $iosLink
320 $workLink = createWorkLink $iosLink
321 if((isValidToken $droidLink) -eq $false -or (isValidToken $iosLink) -eq $false) {
322 log "Detected invalid token URL for $token, skipping"
323 }
324 else {
325 $email = ($tokenFile -split '.sdtid')[0] -replace "\'", "''"
326 $checkQuery = "select count(*) from rsaSoftTokens where email = '$email' and droidLink = '$droidLink' and iosLink = '$iosLink' and workLink='$workLink'"
327 $exists = queryDb $invDbString $checkQuery
328 if($exists[0] -eq 0) {
329 log "Adding/Modifying token for $email"
330 $query = "exec sp_updateRsaSoftToken2 '$id', '$email', '$droidLink', '$iosLink', '$workLink'"
331 queryDb $invDbString $query
332 $email = $email -replace "''", "'"
333 sendToken $email
334 }
335 }
336 }
337 }
338 $now = Get-Date
339 $runTime = (New-TimeSpan -Start $startTime -End $now).TotalSeconds
340 $tps = $i / $runTime
341 log "Processed $tokenCount tokens in $runTime seconds ($tps/sec)"
342 }
343}
344
345###processStaging() - reads all sdtid tokens from the staging folder. tokens are provisioned by IS and named by ID. script renames to email and moves file to tokenDir.
346function processStaging() {
347 #$tokens = Get-ChildItem $stagingDir -filter "*.sdtid"
348 $tokens = @(Get-ChildItem $stagingDir -filter "*.sdtid") + @(Get-ChildItem $stagingDir2 -filter "*.sdtid")
349 if($tokens -eq $null) {
350 log "No new tokens found in staging"
351 } else {
352 foreach($token in $tokens) {
353 #$id = $token.name.split('.')[0]
354 $id = $token.name.split('_')[0]
355 $tokenSrcPath = $token.FullName
356 log "Found new token in staging for $id. Looking up."
357 $user = getDirectoryUser $id
358 if($user -eq $null) {
359 log "No directory user found for $id"
360 } else {
361 $tokenDstPath = "$tokenDir\$($user.mail).sdtid"
362 log "Found directory user $($user.mail). New token path $tokenDstPath"
363 $exists = Get-Item $tokenDstPath -ErrorAction SilentlyContinue
364 if($exists) {
365 $backupTokenPath = "$($tokenDstPath).$(Get-Date -Format yyymmddhhmmss)"
366 log "Backing up existing token to $backupTokenPath"
367 Move-Item $tokenDstPath $backupTokenPath -Force
368 }
369 Copy-Item $tokenSrcPath "$tokenDir2\$($user.mail).sdtid" -Force
370 Move-Item $tokenSrcPath $tokenDstPath
371 Get-Item $tokenDstPath | % {$_.LastWriteTime = Get-Date}
372 }
373 }
374 }
375}
376
377###createWorkLink() - function to create ctf link formatted for Good Work. pass in iOS format link from tokenconverter.exe, as it's pretty close.
378function createWorkLink($iosLink) {
379 $workLink = ([String]$iosLink).replace('com.rsa.securid://ctf?', 'http://ctf/?')
380 #log "Creating Work link: $workLink"
381 $workLink
382}
383
384function createTestLink($iosLink) {
385 $testLink = $iosLink
386}
387
388##createDroidLink($iosLink) - creates droid format from ios format link. faster than calling back out to shell for tokenconverter.exe.
389function createDroidLink($iosLink) {
390 $droidLink = ([String]$iosLink).replace('com.rsa.securid://', 'http://127.0.0.1/securid/')
391 #log "Creating droid link: $droidLink"
392 $droidLink
393}
394
395###processTokens() - update database with tokens from the network share.
396function processTokens() {
397 $timestamp = (readFlag).LastWriteTime
398 if($timestamp -le 0) {
399 log "Flag timestamp is not valid. Exiting."
400 exit
401 }
402 log "processing tokens in $tokenDir modified since $timestamp"
403 writeFlag
404 $newFiles = Get-ChildItem $tokenDir -filter "*.sdtid" | Where-Object {$_.LastWriteTime -gt $timestamp}
405 if($newFiles -eq $null) {
406 $tokens = @()
407 } elseif ($newFiles.getType().BaseType -ne "System.Array") {
408 $tokens = @()
409 $tokens += $newFiles
410 }
411 $tokenConverterPath = ".\TokenConverter.exe"
412 $tokenCount = $tokens.Count
413 log "found $tokenCount tokens"
414 $i = 0
415 $updates = 0
416 $startTime = Get-Date
417 foreach($token in $tokens) {
418 log "processing token $token"
419 $i += 1
420 ###use tokenconverter to generate URLs for Android and iOS
421 #$droidCmd = $tokenConverterPath + " " + $tokenDir + "\" + '"$token"' + " -android"
422 #Invoke-Expression -Command $droidCmd -OutVariable droidLink | Out-Null #powershell v3 syntax
423 #$droidLink = Invoke-Expression -Command $droidCmd #| Out-Null
424 #$id = $token.split("_")[0]
425 $iosCmd = $tokenConverterPath + " " + $tokenDir + "\" + '"$token"' + " -mobile"
426 #$iosCmd = $tokenConverterPath + " " + $tokenDir + "\" + '"$id"' + " -mobile"
427 #Invoke-Expression -Command $iosCmd -OutVariable iosLink | Out-Null #powershell v3 syntax
428 $iosLink = Invoke-Expression -Command $iosCmd #| Out-Null
429 $droidLink = createDroidLink $iosLink
430 $workLink = createWorkLink $iosLink
431 ###if either tests return false, don't process
432 if((isValidToken $droidLink) -eq $false -or (isValidToken $iosLink) -eq $false) {
433 log "detected invalid token url for $token, skipping"
434 } else {
435 ###parse token name into email address and build query.
436 ###sp takes three params and does an insert or update based on email.
437 ###assuming one token per email. otherwise, last entry overwrites.
438 $email = ($token -split '.sdtid')[0] -replace "\'", "''"
439 $checkQuery = "select count(*) from rsaSoftTokens where email = '$email' and droidLink = '$droidLink' and iosLink = '$iosLink' and workLink='$workLink'"
440 $exists = queryDb $invDbString $checkQuery
441 if($exists[0] -eq 0) {
442 log "adding/modifying token for $email"
443 $query = "exec sp_updateRsaSoftToken '$email', '$droidLink', '$iosLink', '$workLink'"
444 #log $query
445 queryDb $invDbString $query
446 sendToken $email
447 $updates += 1
448 }
449 }
450 }
451 $now = Get-Date
452 $runTime = (New-TimeSpan -Start $startTime -End $now).TotalSeconds
453 $tps = $i / $runTime
454 log "processed $tokenCount tokens in $runTime seconds ($tps/sec)"
455}
456
457###sendToken - send token to a given email
458###user must also exist in Good for Enterprise
459###sendToken - send token to a given email
460###user must also exist in Good for Enterprise
461function sendToken($email) {
462 log "Evaluating token for $email"
463 #$cleanEmail = ($user.email).replace("'", "''")
464 #write-host $cleanEmail
465 #$isGoodUser = (isGoodUser $email)
466 #$isWorkUser = (isWorkUser $email)
467 #$doSend = $false
468 #$templateHtml = $gfeHtml
469 $user = getUser $email
470 #$templateHtml = $gfeHtml
471 #if($isWorkUser -eq $true) {
472 #$doSend = $true
473 $templateHtml = $workHtml
474 #} elseif ($isGoodUser -eq $true) {
475 #$doSend = $true
476 #$templateHtml = $gfeHtml
477 #} else {
478 #log "$email is not a GFE user"
479 ###TODO: add native email template here
480 #}
481 ###if either tests return false, don't email
482 if((isValidToken $user.droidLink) -eq $false -or (isValidToken $user.iosLink) -eq $false -or $doSend -eq $false) {
483 log "Token is invalid. Email will not be sent"
484 } else {
485 $name = $user.firstname + " " + $user.lastname
486 log "Sending email to $email"
487 $droidLink = $user.droidLink
488 $iosLink = $user.iosLink
489 $templateHtml = $templateHtml.Replace("{name}",$user.firstname)
490 $templateHtml = $templateHtml.Replace("{droidLink}",$droidLink)
491 $templateHtml = $templateHtml.Replace("{iosLink}",$iosLink)
492 #-Bcc $mailBcc
493 ## TODO REMOVE COMMENT
494 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To $email -Bcc $mailBcc -Subject $mailSubject -BodyAsHtml $templateHtml
495 "Email sent to " + $user.firstname + "at " + $email
496 log "Email sent to $email"
497 }
498}
499function testFunction(){
500 "test"
501}
502
503function sendWorkToken($user) {
504 #$user = getUser $email
505 ###if either tests return false, don't email
506 #if(((isValidToken $user.workLink) -eq $false) -or ($isWorkUser -eq $false)) {
507 if($user.altEmail -ne $null) {
508 $email = $user.altEmail
509 } else {
510 $email = $user.email
511 }
512 if($user.name -eq $null) {
513 $user.name = ""
514 }
515 $templateHtml = $workHtml
516 $isWorkUser = isWorkUser $email
517 if(((isValidToken $user.workLink) -eq $false)) {
518 log "Not sending mail"
519 } else {
520 $name = $user.firstname + " " + $user.lastname
521 log "Sending email to $email"
522 $templateHtml = $templateHtml.Replace("{name}",$user.firstname)
523 $templateHtml = $templateHtml.Replace("{iosLink}",$user.iosLink)
524 $templateHtml = $templateHtml.Replace("{droidLink}",$user.droidLink)
525 #-Bcc $mailBcc
526 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To $email -Bcc $mailBcc -Subject $mailSubject -BodyAsHtml $templateHtml
527 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To $email -Bcc "ryan_hunt@hcsc.net", "damon_richardson@bcbstx.com", "julie_lemke@bcbsil.com" -Subject $mailSubject -BodyAsHtml $templateHtml
528 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To ryan_hunt@hcsc.net -Subject $mailSubject -BodyAsHtml $templateHtml
529 log "Email sent to $email"
530 }
531}
532
533###sendTokens - sends tokens to a collection of users
534function sendTokens($users) {
535 if($users -ne $null) {
536 foreach($user in $users) {
537 $email = $user.email
538 sendWorkToken $user
539 }
540 }
541}
542
543###getUsers - load all soft token users into a collection from the database
544function getUsers() {
545 $users = @()
546 $query = "exec sp_getRsaSoftTokenUsers"
547 $result = queryDb $invDbString $query
548 if($result.count -gt 0) {
549 foreach($row in $result) {
550 $user = New-Object system.object
551 $displayname = $row[2] + ", " + $row[1] | echo
552 $user | Add-Member -type noteproperty -name name -value $displayname
553 $user | Add-Member -type noteproperty -name empid -value $row[0]
554 $user | Add-Member -type noteproperty -name firstname -value $row[1]
555 $user | Add-Member -type noteproperty -name lastname -value $row[2]
556 $user | Add-Member -type noteproperty -name email -value $row[3]
557 $user | Add-Member -type noteproperty -name droidLink -value $row[4]
558 $user | Add-Member -type noteproperty -name iosLink -value $row[5]
559 $user | Add-Member -type noteproperty -name workLink -value $row[6]
560 $users += $user
561 }
562 $users
563 }
564}
565
566###getUser - load user from database
567function getUser($email) {
568 $cleanEmail = $email.replace("'", "''")
569 $query = "exec sp_getRsaSoftTokenUsers '$cleanEmail'"
570 $row = queryDb $invDbString $query
571 if(!($row)) {
572 log "Email $email was not found in the database. Refining search by network ID"
573 $query = "exec sp_getRsaSoftTokenUsers2 '$cleanEmail'"
574 $row = queryDb $invDbString $query
575 }
576 if($row) {
577 $user = New-Object system.object
578 $displayname = $row[2] + ", " + $row[1] | echo
579 $user | Add-Member -type noteproperty -name name -value $displayname
580 $user | Add-Member -type noteproperty -name empid -value $row[0]
581 $user | Add-Member -type noteproperty -name firstname -value $row[1]
582 $user | Add-Member -type noteproperty -name lastname -value $row[2]
583 $user | Add-Member -type noteproperty -name email -value $row[3]
584 $user | Add-Member -type noteproperty -name droidLink -value $row[4]
585 $user | Add-Member -type noteproperty -name iosLink -value $row[5]
586 $user | Add-Member -type noteproperty -name workLink -value $row[6]
587 $user
588 }
589 else {
590 log "Error... $email was not found in the database"
591 $null
592 }
593}
594
595##getUsersByAge - looks in GMC database for users activated in the last $mins minutes and checks for soft tokens
596##Users w/ soft tokens are returned in a collection
597##Users w/o soft tokens are ignored
598function getUsersByAge($mins) {
599 log "looking for activations in the last $mins minutes"
600 $mins = $mins * -1
601 $emails = @()
602 $users = @()
603 $goodQuery = "select distinct email_address from gd_entities where emf_prov_time > DATEADD(mi, $mins, GETDATE()) and len(email_address) > 2 and email_address not in (select emailAddress from move_handheld where stateTime > DATEADD(mi, $mins, GETDATE()))"
604 write-host $goodQuery
605 $gdUsers = queryDb $goodDbString $goodQuery
606 if($gdUsers.count -gt 0) {
607 ##powershell squashes collections have one multidimentional element.
608 ##there should be laws against stuff like this.
609 ##result[0] should still be an object. always.
610 if($gdUsers[0].GetType().fullname -eq "System.String") {
611 $gdUsers = ,($gdUsers)
612 }
613 foreach($gdUser in $gdUsers) {
614 log $gdUser
615 $emails += $gdUser[0]
616 }
617 foreach($email in $emails) {
618 $tokenQuery = "exec sp_getRsaSoftTokenUsers '$email'"
619 log $tokenQuery
620 $rsaUser = queryDb $invDbString $tokenQuery
621 if($rsaUser -ne $null -and $rsaUser[0].length -gt 0) {
622 $user = New-Object system.object
623 $displayname = $rsaUser[2] + ", " + $rsaUser[1] | echo
624 $user | Add-Member -type noteproperty -name name -value $displayname
625 $user | Add-Member -type noteproperty -name empid -value $rsaUser[0]
626 $user | Add-Member -type noteproperty -name email -value $rsaUser[3]
627 $user | Add-Member -type noteproperty -name droidLink -value $rsaUser[4]
628 $user | Add-Member -type noteproperty -name iosLink -value $rsaUser[5]
629 $user | Add-Member -type noteproperty -name workLink -value $rsaUser[6]
630 $users += $user
631 }
632 }
633 $users
634 }
635}
636
637function getWorkUsersByAge($mins) {
638 log "looking for activations in the last $mins minutes"
639 $emails = @()
640 $users = @()
641 $goodQuery = "select distinct prov_id from t_gc_containers where native_display_name = 'Good Work' and DATEDIFF(MINUTE, DATEADD(s, activation_date/1000, '1970-01-01'), GETUTCDATE()) < $mins"
642 write-host $goodQuery
643 $gdUsers = queryDb $gcDbString $goodQuery
644 if($gdUsers.count -gt 0) {
645 ##powershell squashes collections have one multidimentional element.
646 ##there should be laws against stuff like this.
647 ##result[0] should still be an object. always.
648 if($gdUsers[0].GetType().fullname -eq "System.String") {
649 $gdUsers = ,($gdUsers)
650 }
651 foreach($gdUser in $gdUsers) {
652 log $gdUser
653 $emails += $gdUser[0]
654 }
655 foreach($email in $emails) {
656 $tokenQuery = "exec sp_getRsaSoftTokenUsers '$email'"
657 log $tokenQuery
658 $rsaUser = queryDb $invDbString $tokenQuery
659 if($rsaUser -ne $null -and $rsaUser[0].length -gt 0) {
660 $user = New-Object system.object
661 $displayname = $rsaUser[2] + ", " + $rsaUser[1] | echo
662 $user | Add-Member -type noteproperty -name name -value $displayname
663 $user | Add-Member -type noteproperty -name empid -value $rsaUser[0]
664 $user | Add-Member -type noteproperty -name email -value $rsaUser[3]
665 $user | Add-Member -type noteproperty -name droidLink -value $rsaUser[4]
666 $user | Add-Member -type noteproperty -name iosLink -value $rsaUser[5]
667 $user | Add-Member -type noteproperty -name workLink -value $rsaUser[6]
668 $users += $user
669 }
670 }
671 $users
672 }
673}
674
675function getUsersByTokenAge($days) {
676 $date = (Get-Date).AddDays($days * -1)
677 $tokens = Get-ChildItem $tokenDir -Filter "*.sdtid" | Where-Object {$_.LastWriteTime -ge $date }
678 $users = @()
679 $tokens | % {
680 $email = ($_.Name -split '.sdtid')[0] -replace "\'", "''"
681 $user = getUser $email
682 $users += $user
683 }
684 $users
685}
686
687###getUsersFromExcel - load users from an excel spreadsheet
688### $file = path
689### $column = column that contains email addresses, index starts at 1
690### $startRow = row number to start import, index starts at 1
691function getUsersFromExcel($file, $column, $startRow) {
692 $emails = @()
693 $users = @()
694 $ss = New-Object -ComObject Excel.Application
695 $ss.Visible = $false
696 $wb = $ss.Workbooks.Open($file)
697 $wb.Sheets.Select(0)
698 $sheet = $wb.ActiveSheet
699 $rows = ($sheet.UsedRange.Rows).count
700 Write-Host "loaded worksheet with $rows rows"
701 for($i=$startRow;$i -le $rows;$i++) {
702 $value = $sheet.Cells.Item($i, $column).Text
703 if($value -eq "") {
704 Write-Host "encountered empty row, breaking"
705 break
706 }
707 if($value -match "@") {
708 $query = "exec sp_getRsaSoftTokenUsers '$value'"
709 $row = queryDb $invDbString $query
710 if($row -ne $null -and $row[0].length -gt 0) {
711 $user = New-Object system.object
712 $displayname = $row[2] + ", " + $row[1] | echo
713 $user | Add-Member -type noteproperty -name name -value $displayname
714 $user | Add-Member -type noteproperty -name empid -value $row[0]
715 $user | Add-Member -type noteproperty -name email -value $row[3]
716 $user | Add-Member -type noteproperty -name droidLink -value $row[4]
717 $user | Add-Member -type noteproperty -name iosLink -value $row[5]
718 $users += $user
719 }
720 }
721 }
722 $users
723}
724
725
726# Why tho
727###getUsersFromExcel - load users from an excel spreadsheet
728### $file = path
729### $colEmail = column that contains email addresses, index starts at 1
730### $colId = column that contains login ID
731### $startRow = row number to start import, index starts at 1
732function getAltUsersFromExcel($file, $colId, $colEmail, $startRow) {
733 $colId = 1
734 $colemail = 2
735 $startRow = 1
736 $emails = @()
737 $users = @()
738 $errors = @()
739 Write-Host "Starting import process, please wait..."
740 $ss = New-Object -ComObject Excel.Application
741 $ss.Visible = $false
742 $wb = $ss.Workbooks.Open($file)
743 $wb.Sheets.Select(0)
744 $sheet = $wb.ActiveSheet
745 $rows = ($sheet.UsedRange.Rows).count
746 if ($rows -gt 0) {
747 Write-Host "Loaded worksheet with $rows rows"
748 } else {
749 Write-Host "Error... Path entered to Excel spreadsheet may be incorrect"
750 }
751 for ($i=$startRow;$i -le $rows;$i++) {
752 $id = $sheet.Cells.Item($i, $colId).Text
753 if($id -eq "") {
754 Write-Host "Encountered empty row, breaking."
755 break
756 }
757 $query = "select distinct empid from new_hr where empid like '$id'"
758 $adUser = queryDb $invDbString $query
759 $altEmail = $sheet.Cells.Item($i, $colEmail).Text
760 if ($adUser) {
761 $query = "select distinct email from new_hr where empid like '$id'"
762 $email = queryDb $invDbString $query
763 $email = $email -replace "'", "''"
764 $query = "exec sp_getRsaSoftTokenUsers '$email'"
765 $row = queryDb $invDbString $query
766 if (!($row)) {
767 log "User not found by email in HR table. Trying search using network ID"
768 $query = "select distinct networkid from new_hr where empid like '$id'"
769 $networkId = queryDb $invDbString $query
770 if ($networkId) {
771 $query = "select distinct email from rsaSoftTokens where networkid like '$networkId'"
772 $email = queryDb $invDbString $query
773 $email = $email -replace "'", "''"
774 $query = "exec sp_getRsaSoftTokenUsers2 '$email'"
775 $row = queryDb $invDbString $query
776 }
777 }
778 if ($row) {
779 $user = New-Object system.object
780 $displayname = $row[2] + ", " + $row[1] | echo
781 $user | Add-Member -type NoteProperty -name id -value $id
782 $user | Add-Member -type noteproperty -name name -value $displayname
783 $user | Add-Member -type noteproperty -name empid -value $row[0]
784 $user | Add-Member -type noteproperty -name email -value $email
785 $user | Add-Member -type noteproperty -name firstname -value $row[1]
786 $user | Add-Member -type noteproperty -name altEmail -value $altEmail
787 $user | Add-Member -type noteproperty -name droidLink -value $row[4]
788 $user | Add-Member -type noteproperty -name iosLink -value $row[5]
789 $user | Add-Member -type noteproperty -name workLink -value $row[6]
790 $users += $user
791 log "Found user $displayname in HR table"
792 } else {
793 log "User could not be verified. Skipping ID $id"
794 }
795 } else {
796 log "Skipping ID $id. ID does not exist in database. Please verify ID and try again"
797 }
798 }
799 $wb.Close()
800 $ss.Quit()
801 if ($users) {
802 log "Testing tokens and emailing to external users"
803 }
804 sendExtTokens($users)
805}
806
807# Takes in multi-user input to run the Send command multiple times
808
809# Sending out emails via information gleaned from the spreadsheet
810# sendExtTokens - Input $users -- an array of user objects, with an attached email
811
812function sendExtTokens($users) {
813 if($users -ne $null) {
814 foreach($user in $users) {
815 $email = $user.email
816 sendExtToken $user
817 }
818 }
819 Write-Host "Batch process completed"
820}
821
822
823#============================================================================
824#sendExtTokens - Input $user -- a user object, with an attached mailing address
825# Least Trivial Input : $user object, an email
826# TODO Use this function without an excel sheet
827function sendExtToken($user) {
828 #$user = getUser $email
829 ###if either tests return false, don't email
830 #if(((isValidToken $user.workLink) -eq $false) -or ($isWorkUser -eq $false)) {
831 if($user.altEmail -ne $null -and $user.altEmail -like "*@*" -and $user.altEmail -like "*.*") {
832 $email = $user.altEmail
833 } else {
834 $email = $user.email
835 }
836 if($user.name -eq $null) {
837 $user.name = ""
838 }
839 #$templateHtml = $workHtml
840 #$isWorkUser = isWorkUser $email
841 if((isValidToken $user.droidLink) -eq $false -or (isValidToken $user.iosLink) -eq $false) {
842 log "Token failed validation. Email will not be sent"
843 } else {
844 $name = $user.firstname + " " + $user.lastname
845 log "Sending email to $email"
846 #$templateHtml = $templateHtml.Replace("{name}",$user.firstname)
847 #$templateHtml = $templateHtml.Replace("{iosLink}",$user.iosLink)
848 #$templateHtml = $templateHtml.Replace("{droidLink}",$user.droidLink)
849 $bodyHtml = $templateHtmlExt
850 $bodyHtml = $bodyHtml.Replace("{name}",$user.firstname)
851 $bodyHtml = $bodyHtml.Replace("{droidLink}",$user.droidLink)
852 $bodyHtml = $bodyHtml.Replace("{iosLink}",$user.iosLink)
853 $message = new-object System.Net.Mail.MailMessage
854 $message.From = $mailFrom
855 $message.To.Add($email)
856 #$message.CC.Add($mailCC)
857 #$message.Bcc.Add($mailBccExt)
858 $message.IsBodyHtml = $True
859 #$message.Subject = $mailSubject
860 $message.Subject = $mailSubjectExt
861 $attach = new-object Net.Mail.Attachment($attachment)
862 $message.Attachments.Add($attach)
863 $message.body = $bodyHtml
864 $smtp = new-object Net.Mail.SmtpClient($smtpServer)
865 $smtp.Send($message)
866 #-Bcc $mailBcc
867 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To $email -Bcc $mailBcc -Subject $mailSubject -BodyAsHtml $templateHtml
868 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To $email -Bcc "ryan_hunt@hcsc.net", "damon_richardson@bcbstx.com", "julie_lemke@bcbsil.com" -Subject $mailSubject -BodyAsHtml $templateHtml
869 #Send-MailMessage -SmtpServer $smtpServer -From $mailFrom -To ryan_hunt@hcsc.net -Subject $mailSubject -BodyAsHtml $templateHtml
870 log "Email sent to $email"
871 }
872}
873#============================================================================
874
875###this is the main function that builds the WinForms UI and sets things off.
876function showInterface() {
877 Write-Host $nl"Launching interface..."
878 $users = @()
879 $users = getUsers
880 $userSource = New-Object System.Collections.ArrayList
881 $userSource.AddRange($users)
882 $recipientSource = New-Object System.Collections.ArrayList
883
884 ###using windows.forms for user prompt
885 $formW = 500
886 $formH = 620
887
888 $labelW = $formW
889 $labelH = 40
890
891 $label2W = 120
892 $label2H = 13
893
894 $label3W = 360
895 $label3H = 17
896
897 $marginW = 60
898
899 $searchH = 20
900
901 $listW = 150
902 $listH = 400
903 $listSpacerW = 60
904
905 $addButtonW = 40
906 $addButtonH = 20
907 $addButtonSpace = 10
908
909 $buttonW = 90
910 $buttonH = 25
911
912 $form = New-Object 'System.Windows.Forms.Form'
913 $form.StartPosition = "CenterScreen"
914 $form.BackColor="White"
915 $form.Size = New-Object System.Drawing.Size($formW, $formH)
916 $form.Icon = New-Object system.drawing.icon ("$myPath\hcsc.ico")
917 $form.Text = "HCSC - RSA Soft Token Helper v1.2.13"
918
919 $label = New-Object System.Windows.Forms.Label
920 $label.Size = New-Object System.Drawing.Size($labelW, $label3H)
921 $label.Location = "83,22"
922 $label.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 9)
923 $label.Text = "Employee Search"
924
925 $label2 = New-Object System.Windows.Forms.Label
926 $label2.Size = New-Object System.Drawing.Size($label3W, $label2H)
927 $label2.Location = "123,548"
928 $label2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 8)
929 $label2.Text = "Full Path to Excel File (ie c:\temp\import.xlsx)"
930
931 # External Batch GUI
932 $label3 = New-Object System.Windows.Forms.Label
933 $label3.Size = New-Object System.Drawing.Size($label3W, $label3H)
934 $label3.Location = "92,507"
935 $label3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 10,[System.Drawing.FontStyle]::Bold)
936 $label3.Text = "*** External Email Batch Process Only ***"
937
938 $label4 = New-Object System.Windows.Forms.Label
939 $label4.Size = New-Object System.Drawing.Size($label3W, $label2H)
940 $label4.Location = "133,562"
941 $label4.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 8)
942 $label4.Text = "Excel Format (Col1-EmpID | Col2-Email)"
943
944 $userSearch = New-Object System.Windows.Forms.TextBox
945 $userSearch.Location = New-Object System.Drawing.Size($marginW, $labelH)
946 $userSearch.Size = New-Object System.Drawing.Size($listW, 50)
947 $userSearch.Text = ""
948 $userSearch.Add_keyDown({
949 })
950 $userSearch.Add_keyUp({
951 $searchText = $userSearch.Text
952 $result = @()
953 $result = $userSource | Where-Object {$_.name -match $searchText}
954 $resultSource = New-Object System.Collections.ArrayList
955 #$resultSource.AddRange($result)
956 if($result.getType().fullname -eq "System.Object") {
957 $cResult = ,($result)
958 $resultSource.AddRange($cResult)
959 } else {
960 $resultSource.AddRange($result)
961 }
962 $userList.DataSource = $null
963 $userList.DisplayMember = "name"
964 $userList.DataSource = $resultSource
965 })
966
967 $userList = New-Object System.Windows.Forms.ListBox
968 $userList.Size = New-Object System.Drawing.Size($listW, $listH)
969 $y = $labelH + $searchH + 5
970 $userList.Location = New-Object System.Drawing.Size($marginW, $y)
971 $userList.SelectionMode = "MultiExtended"
972 $userList.Sorted = $true
973 $userList.DisplayMember = "name"
974 $userList.DataSource = $userSource
975
976 $rcptList = New-Object System.Windows.Forms.ListBox
977 $rcptList.Size = New-Object System.Drawing.Size($listW, $listH)
978 $x = $marginW + $listW + $listSpacerW
979 $y = $labelH + $searchH + 5
980 $rcptList.Location = New-Object System.Drawing.Size($x, $y)
981 $rcptList.DisplayMember = "name"
982 $rcptList.SelectionMode = "MultiExtended"
983 $rcptList.Sorted = $true
984 $rcptList.DataSource = $recipientSource
985
986 $addButton = New-Object System.Windows.Forms.Button
987 $x = $marginW + $listW + $addButtonSpace
988 $y = $labelH + ($listH / 3)
989 $addButton.Text = " > "
990 $addButton.Location = New-Object System.Drawing.Size($x, $y)
991 $addButton.Size = New-Object System.Drawing.Size($addButtonW, $addButtonH)
992 $addButton.Add_Click({
993 $selected = $userList.SelectedItems
994 $recipientSource.AddRange($selected)
995 foreach($item in $userList.SelectedItems) {
996 $userSource.Remove($item)
997 }
998 $searchText = $userSearch.Text
999 $result = @()
1000 $result = $userSource | Where-Object {$_.name -match $searchText}
1001 $resultSource = New-Object System.Collections.ArrayList
1002 if($result.getType().fullname -eq "System.Object") {
1003 $resultSource.Add($result)
1004 } else {
1005 $resultSource.AddRange($result)
1006 }
1007 $userList.DataSource = $null
1008 $userList.DisplayMember = "name"
1009 $userList.DataSource = $resultSource
1010
1011 $rcptList.DataSource = $null
1012 $rcptList.DisplayMember = "name"
1013 ##
1014 $rcptList.DataSource = $recipientSource
1015 })
1016
1017 $rmButton = New-Object System.Windows.Forms.Button
1018 $x = $marginW + $listW + $addButtonSpace
1019 $y = $labelH + ($listH / 3) + $addButtonH + $addButtonSpace
1020 $rmButton.Text = " < "
1021 $rmButton.Location = New-Object System.Drawing.Size($x, $y)
1022 $rmButton.Size = New-Object System.Drawing.Size($addButtonW, $addButtonH)
1023 $rmButton.Add_Click({
1024 $selected = $rcptList.SelectedItems
1025 #Write-Host $rcptList.SelectedIndices
1026 foreach($item in $rcptList.SelectedItems) {
1027 $recipientSource.Remove($item)
1028 $userSource.Add($item)
1029 }
1030
1031 #$recipientSource.Remove($selected)
1032 $rcptList.DataSource = $null
1033 $rcptList.DisplayMember = "name"
1034 $rcptList.DataSource = $recipientSource
1035
1036 $searchText = $userSearch.Text
1037 $result = @()
1038 $result = $userSource | Where-Object {$_.name -match $searchText}
1039 $userSource = New-Object System.Collections.ArrayList
1040 $userSource.AddRange($users)
1041 $userList.DataSource = $null
1042 $userList.DisplayMember = "name"
1043 $userList.DataSource = $userSource
1044 })
1045
1046 ###Import directory path text field for eternal email addresses
1047 $importPathTextField = New-Object System.Windows.Forms.TextBox
1048 $x = $marginW + 50
1049 $y = $labelH + $searchH + $listH + $labelH + 26
1050 $importPathTextField.Location = New-Object System.Drawing.Size($x, $y)
1051 $importPathTextField.Size = New-Object System.Drawing.Size($listW, $labelH)
1052 $importPathTextField.Text = "$importDir"
1053
1054 ###Button to import and send to external address in source listbox with data from directory path
1055 $importSendButton = New-Object System.Windows.Forms.Button
1056 $x = $marginW + $listW + $listSpacerW + 9
1057 $y = $labelH + $searchH + $listH + $labelH + 26
1058 $importSendButton.Location = New-Object System.Drawing.Size($x, $y)
1059 $importSendButton.Size = New-Object System.Drawing.Size($buttonW, 20)
1060 $importSendButton.Text = "Import | Send"
1061 $importSendButton.Add_Click({
1062 getAltUsersFromExcel($importPathTextField.Text)
1063 })
1064
1065
1066
1067
1068 $updateButton = New-Object System.Windows.Forms.Button
1069 $x = $marginW + (($listW / 2) - ($buttonW / 2))
1070 $y = $labelH + $searchH + $listH + 5
1071 $updateButton.Location = New-Object System.Drawing.Size($x, $y)
1072 $updateButton.Size = New-Object System.Drawing.Size($buttonW, 20)
1073 $updateButton.Text = "Update"
1074 $updateButton.Add_Click({
1075 Write-Host "updating"
1076 processTokens
1077 $users = @()
1078 $users = getUsers
1079 $resultSource = New-Object System.Collections.ArrayList
1080 $resultSource.AddRange($users)
1081 $userList.DataSource = $null
1082 $userList.DisplayMember = "name"
1083 $userList.DataSource = $resultSource
1084 })
1085 $sendButton = New-Object 'System.Windows.Forms.Button'
1086 $sendButton.Anchor = 'Bottom, Left'
1087 $y = $labelH + $searchH + $listH + 10
1088 $sendButton.Location = New-Object System.Drawing.Size(250, $y)
1089 $sendButton.Name = "closeButton"
1090 $sendButton.Size = '90, 25'
1091 $sendButton.Text = "Send"
1092 $sendButton.Add_Click({
1093 foreach($user in $recipientSource) {
1094 sendToken($user.email)
1095 }
1096 $recipientSource.RemoveRange(0,$recipientSource.count)
1097 $recipientSource = New-Object System.Collections.ArrayList
1098 $rcptList.DataSource = $null
1099 $rcptList.DisplayMember = "name"
1100 $rcptList.DataSource = $recipientSource
1101
1102 $userSearch.Text = ""
1103 $userList.DataSource = $null
1104 $userSource = New-Object System.Collections.ArrayList
1105 $userSource.AddRange($users)
1106 $userList.DisplayMember = "name"
1107 $userList.DataSource = $userSource
1108 })
1109
1110
1111 $closeButton = New-Object 'System.Windows.Forms.Button'
1112 $closeButton.Anchor = 'Bottom, Left'
1113 $y = $labelH + $searchH + $listH + 10
1114 $closeButton.Location = New-Object System.Drawing.Size(140, $y)
1115 $closeButton.Name = "closeButton"
1116 $closeButton.Size = '90, 25'
1117 $closeButton.Text = "Close"
1118 $closeButton.Add_Click({
1119 $form.Dispose()
1120 })
1121
1122 $form.Controls.Add($label)
1123 $form.Controls.Add($label2)
1124 $form.Controls.Add($label3)
1125 $form.Controls.Add($label4)
1126 $form.Controls.Add($userSearch)
1127 #$form.Controls.Add($updateButton)
1128 $form.Controls.Add($userList)
1129 $form.Controls.Add($rcptList)
1130 $form.Controls.Add($addButton)
1131 $form.Controls.Add($rmButton)
1132 $form.Controls.Add($importPathTextField)
1133 $form.Controls.Add($importSendButton)
1134 $form.Controls.Add($closeButton)
1135 $form.Controls.Add($sendButton)
1136 #$form.TopMost = $true
1137 $form.ShowDialog()
1138}
1139if($gui -eq $true) {
1140 showInterface
1141}