SecureTransport - Account Audit Report Script

While you can review account information from the SecureTransport (ST) admin interface if you want to generate reports on unused accounts or accounts that do not have a password expiry interval you extract this information and output this information as a HTML report using PowerShell. You might also want to do this if you want to provide this information to an individual but don't necessarily want to provide access to the administrative interface (you can limit what an admin user can do by creating a role with custom permissions).

The script is provided below which will need to be modified to reflect:
  • The drive where ST has been installed
  • The MySQL password for your environment
  • The password expiry threshold based on which you want accounts to be flagged on
The script requires that you have the MySQL Connector for .NET installed. The script assumes that ST has been deployed in a "streaming configuration" with an Internet facing SecureTransport Edge server and an internal SecureTransport server. You'll need to modify the InternalSTServer variable to match the hostname of your internal ST server.


The source code is also available on GitHub https://github.com/vijayjt/SecureTransportScripts

  1. <#     
  2.     .SYNOPSIS     
  3.         Check expiry dates of SecureTransport user account passwords  
  4.     .DESCRIPTION     
  5.           
  6.           
  7.     .PARAMETER    
  8.         -SkipUserNotification  
  9.             Specifying this switch will prevent the script from notifying users if their password is expiring soon. This is useful if the script is run on an ad-hoc basis and you do not wish to notify the users because the script already runs a a scheduled task.  
  10.           
  11.     .EXAMPLE     
  12.           
  13.           
  14.     .NOTES    
  15.         File Name  : gen-account-audit-report.ps1   
  16.         Author     : Vijay Thakorlal  
  17.         Requires   : PowerShell V2  
  18.         To Do      : Use read-secure string to store credentials in a file  
  19.           
  20.         IMPORTANT NOTES  
  21.             1. You must change the password to the mysql database password set during installation of SecureTransport  
  22.           
  23. #>     
  24.   
  25. [CmdletBinding()]  
  26. param([Switch]$SkipUserNotification)  
  27.   
  28. ############################  
  29. # BEGIN VARIABLE DEFINITIONS  
  30. ############################  
  31.   
  32. # Get the hostname  
  33. $servername = $env:COMPUTERNAME  
  34. # Modify this variable to match your environment  
  35. $InternalSTServer = "INTERNALSERVER"  
  36.   
  37. # MySQL Connection String  
  38. $MySQLServer = "localhost"  
  39. $MySQLPort = "33060"  
  40. $MySQLUser = "root"  
  41. $MySQLPassword = "tumbleweed"  
  42. $MySQLDatbase = "st"  
  43. $connString = "Server=$MySQLServer;port=$MySQLPort;Uid=$MySQLUser;Pwd=$MySQLPassword;database=$MySQLDatbase;"  
  44.   
  45. # Threshold in days based on which to report on expiring passwords / accounts  
  46. # E.g. report on accounts that are due to expire in 14 days or less  
  47. $passwd_expiry_threshold = 14  
  48. $unusedThreshold = 30  
  49. $NoPasswordExpirySetAccountsHash = @()  
  50. $UnusedUserAccountsHash = @()  
  51. $DisabledUserAccountsHash = @()  
  52. $NoLoginInXDaysAccountsHash = @()  
  53. $ExpUserPassHash = @()  
  54. $AdminAccStatus = @()  
  55.   
  56. # Administrative account expiry threshold is stored in a configuration file  
  57. $FILEDRIVECONF="C:\Program Files\Tumbleweed\SecureTransport\STServer\conf\filedrive.conf"  
  58.   
  59. # HTML Report File Location  
  60. $ReportPath = "C:\scripts\" 
  61. $ReportFile = Join-Path $ReportPath  "securetransport-accounts-report.html" 
  62.  
  63. ########################### 
  64. # END VARIABLE DEFINITIONS 
  65. ########################### 
  66.  
  67.  
  68. ############################ 
  69. # BEGIN FUNCTION DEFINITIONS 
  70. ############################ 
  71.  
  72. Function get-AdminPassConfig() 
  73. { 
  74.     $content = Get-Content -Path (Resolve-Path $FILEDRIVECONF) -Delimiter "\n" 
  75.     if ( $content -match "(.*)admin\-password\-expiration\s\d+" ) 
  76.     { 
  77.         # We have to use substring here because there appear to be weired control characters before the digits 
  78.         # that are not spaces 
  79.         $expValue = ( [string]($matches[0] -split  "admin\-password\-expiration\s+")).subString(1) 
  80.         return $expValue 
  81.     } 
  82.     return $null 
  83. } # END FUNCTION  get-AdminPassConfig 
  84.  
  85. [string] $admin_password_expiry = get-AdminPassConfig 
  86.  
  87. Function Run-MySQLQuery  
  88. { 
  89.  
  90.     Param( 
  91.         [Parameter( 
  92.             Mandatory = $true, 
  93.             ParameterSetName = '', 
  94.             ValueFromPipeline = $true)] 
  95.             [string]$query,    
  96.         [Parameter( 
  97.             Mandatory = $true, 
  98.             ParameterSetName = '', 
  99.             ValueFromPipeline = $true)] 
  100.             [string]$connectionString 
  101.         ) 
  102.     Begin  
  103.     { 
  104.         Write-Debug "Starting Begin Section"      
  105.     } 
  106.     Process  
  107.     { 
  108.         Write-Debug "Starting Process Section" 
  109.         try  
  110.         { 
  111.             # load MySQL driver and create connection 
  112.             Write-Debug "Create Database Connection" 
  113.             # You could also could use a direct Link to the DLL File the path assumes x86 system and the system has  
  114.             # a version of .NET framework lower than 4.0 if the system is running .NET Framework 4.0 repalce v2.0 with v4.0 in the path 
  115.             # $mySQLDataDLL = "C:\Program Files\MySQL\MySQL Connector Net 6.5.4\Assemblies\v2.0\MySql.Data.dll" 
  116.             # For x64 use 
  117.             # $mySQLDataDLL = "C:\Program Files (x86)\MySQL\MySQL Connector Net 6.5.4\Assemblies\v2.0\MySql.Data.dll" 
  118.             # [void][system.reflection.Assembly]::LoadFrom($mySQLDataDLL) 
  119.             [void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data") 
  120.             $connection = New-Object MySql.Data.MySqlClient.MySqlConnection 
  121.             $connection.ConnectionString = $ConnectionString 
  122.             Write-Debug "Open Database Connection" 
  123.             $connection.Open() 
  124.               
  125.             # Run MySQL Query 
  126.             Write-Debug "Run MySQL Query $query" 
  127.             $command = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $connection) 
  128.             $dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($command) 
  129.             $dataSet = New-Object System.Data.DataSet 
  130.             $dataAdapter.Fill($DataSet) | Out-Null 
  131.             return $DataSet.Tables[0] 
  132.             #$recordCount = $dataAdapter.Fill($dataSet, "data") | Out-Null 
  133.             #return $dataSet.Tables["data"] | Format-Table 
  134.  
  135.         }        
  136.         catch  
  137.         { 
  138.             #Write-Output "Could not run MySQL Query ( $query )" $Error[0] 
  139.             Write-Host "Could not run MySQL Query" $Error[0]     
  140.         }    
  141.         Finally  
  142.         { 
  143.             Write-Debug "Close Connection" 
  144.             $connection.Close() 
  145.         } 
  146.     } 
  147.     End  
  148.     { 
  149.         Write-Debug "Starting End Section" 
  150.     } 
  151. } # END FUNCTION Run-MySQLQuery 
  152.  
  153.  
  154. function is-null($value) 
  155. { 
  156.   return  [System.DBNull]::Value.Equals($value) 
  157. } # END FUNCTION is-null 
  158.  
  159. # Sends email notification to a user whose password is due to expire 
  160. function notify-User ($object) 
  161. { 
  162.     $UserName = $object.("Name") 
  163.     $daysToExpiry =  $object.("Days to Password Expiry") 
  164.     $mailMessage = "This is a notification from SecureTransport. Your password (for the account $UserName) is due to expire in $daysToExpiry days or less. Please change your password at your earliest convenience." 
  165.     $mailSubject = "SecureTransport: Password Expiry Notification" 
  166.     $mailTo = $object.("Email") 
  167.     $mailFrom = "securetransport@acme.com"   
  168.     $SMTPServer = "192.168.0.1" 
  169.      
  170.     $htmlEmail = @"  
  171.     <?xml version="1.0" encoding="UTF-8"?>  
  172.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"  
  173.     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">  
  174.   
  175.     <html xmlns="http://www.w3.org/1999/xhtml">  
  176.         <!-- Created on: 05/06/2005 -->  
  177.         <head>  
  178.             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  179.             <title></title>  
  180.             <style type="text/css">  
  181.                 * {margin: 0; padding: 0;}  
  182.                 body {background: #fff; font: 12px/14px Arial, sans-serif;}  
  183.                 #wrapper { margin: 10px;  border: 1px solid #5c9fce;}  
  184.                 #content { margin: 10px; }  
  185.                 .header { background: #ccc; color: white; padding: 8px; margin: 2px; font-size: 20px; font-weight:normal; }  
  186.                 a:link,a:visited {text-decoration: none; color: blue;}  
  187.                 a:active {text-decoration: none}  
  188.                 a:hover {text-decoration: underline; color: red;}  
  189.             </style>  
  190.         </head>  
  191.         <body>  
  192.             <div id="wrapper">        
  193.                 <br />  
  194.                 <div class="header">  
  195.                 <strongSecureTransport</strong>  
  196.                 </div>  
  197.                 <div id="content">  
  198.                     <br /><br />  
  199.                     <div>  
  200.                     $($mailMessage)  
  201.                     </div>  
  202.                     <br /><br />                      
  203.                 </div>  
  204.             </div>  
  205.         </body>  
  206.     </html>  
  207. "@ 
  208.      
  209.      
  210.     Send-MailMessage -SmtpServer $SMTPServer -From $mailFrom -To $MailTo -Subject $mailSubject -BodyAsHtml $htmlEmail 
  211.      
  212.     Write-Verbose "EXPIRY NOTIFICATION SENT # TO: $mailTo # FROM: $mailFrom # SUBJECT: $mailSibject # MAILMSG: $mailMessage "  
  213. }  
  214.   
  215. function send-Report()  
  216. {  
  217.     $mailMessage = "This is a notification from SecureTransport. Please find attached a HTML report of the accounts on the SecureTransport Server $servername" 
  218.     $mailSubject = "SecureTransport: Password Expiry Notification" 
  219.     $mailTo = "audit@acme.com" 
  220.     $mailFrom = "securetransport@acme.com"   
  221.     $SMTPServer = "192.168.0.1" 
  222.      
  223.     $htmlEmail = @"  
  224.     <?xml version="1.0" encoding="UTF-8"?>  
  225.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"  
  226.     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">  
  227.   
  228.     <html xmlns="http://www.w3.org/1999/xhtml">  
  229.         <!-- Created on: 05/06/2005 -->  
  230.         <head>  
  231.             <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  232.             <title></title>  
  233.             <style type="text/css">  
  234.                 * {margin: 0; padding: 0;}  
  235.                 body {background: #fff; font: 12px/14px Arial, sans-serif;}  
  236.                 #wrapper { margin: 10px;  border: 1px solid #5c9fce;}  
  237.                 #content { margin: 10px; }  
  238.                 .header { background: #00649f; color: white; padding: 8px; margin: 2px; font-size: 20px; font-weight:normal; }  
  239.                 a:link,a:visited {text-decoration: none; color: blue;}  
  240.                 a:active {text-decoration: none}  
  241.                 a:hover {text-decoration: underline; color: red;}  
  242.             </style>  
  243.         </head>  
  244.         <body>  
  245.             <div id="wrapper">  
  246.                 <br />  
  247.                 <div class="header">  
  248.                 <strongSecureTransport</strong>  
  249.                 </div>  
  250.                 <div id="content">  
  251.                     <br /><br />  
  252.                     <div>  
  253.                     $($mailMessage)  
  254.                     </div>  
  255.                     <br /><br />                      
  256.                 </div>  
  257.             </div>  
  258.         </body>  
  259.     </html>  
  260. "@ 
  261.      
  262.      
  263.     Send-MailMessage -SmtpServer $SMTPServer -From $mailFrom -To $MailTo -Subject $mailSubject -BodyAsHtml $htmlEmail -Attachments $ReportFile 
  264.      
  265.     Write-Verbose "EXPIRY NOTIFICATION SENT # TO: $mailTo # FROM: $mailFrom # SUBJECT: $mailSibject # MAILMSG: $mailMessage "  
  266. }  
  267.   
  268. # Returns a given user's email address  
  269. function get-UserEmail($user)  
  270. {  
  271.     $getEmailQuery = "SELECT email from account WHERE name = '$user'" 
  272.     $geqResults = run-MySQLQuery -connectionString $connString -query $getEmailQuery 
  273.      
  274.     if (is-null $geqResults[0] ) { return "No email address configured for $user"  }             
  275.     return $geqResults[0]    
  276. } # END FUNCTION get-UserEmail 
  277.  
  278. # Returns a list of accounts and their status 
  279. function get-DisabledAccounts() 
  280. { 
  281.     $TempHash = @() 
  282.     $ObjProps = @() 
  283.      
  284.     $getAccountStatusQuery = "SELECT name,email,disabled from account WHERE BIN(disabled)='1'" 
  285.     $gasResults = run-MySQLQuery -connectionString $connString -query $getAccountStatusQuery 
  286.      
  287.     if( $gasResults -eq $null ) 
  288.     { 
  289.         $ObjProps = @{'Name'='no users found'; 
  290.             'Email'='-'; 
  291.             'Disabled'='-';} 
  292.         $disabled_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  293.         $TempHash += $disabled_user_accounts_obj 
  294.         return $TempHash 
  295.     } 
  296.      
  297.     foreach ( $row in $gasResults ) 
  298.     { 
  299.         if ( $row.disabled -eq 0) { $UserAccountStatus = "Active"  } 
  300.         elseif ( $row.disabled -eq 1) {  
  301.             $UserAccountStatus = "Disabled"  
  302.             Write-Verbose "User $($row.name) is disabled" 
  303.         } 
  304.         else { $UserAccountStatus = "" } 
  305.                  
  306.         $ObjProps = @{'Name'=$row.name; 
  307.             'Email'=$row.email; 
  308.             'Disabled'=$UserAccountStatus;} 
  309.         $disabled_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  310.         $TempHash += $disabled_user_accounts_obj 
  311.          
  312.     } 
  313.     return $TempHash 
  314. } # END FUNCTION get-AccountStatus 
  315.  
  316.  
  317. function get-UnusedAccounts() 
  318. { 
  319.     $TempHash = @() 
  320.     $ObjProps = @() 
  321.     $gllnQuery = "SELECT LoginName FROM virtualuser WHERE LastLogin IS NULL" 
  322.     $gllnResults = run-MySQLQuery -connectionString $connString -query $gllnQuery 
  323.      
  324.     if( $guawnpeResults -eq $null ) 
  325.     { 
  326.         $ObjProps = @{'Name'='no users found'; 
  327.             'Email'='-';} 
  328.         $unused_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  329.         $TempHash += $unused_user_accounts_obj 
  330.         return $TempHash 
  331.     } 
  332.      
  333.     foreach ( $row in $gllnResults ) 
  334.     { 
  335.         $email = get-UserEmail $row.LoginName 
  336.          
  337.         $ObjProps = @{'Name'=$row.LoginName; 
  338.             'Email'=$email;} 
  339.         $unused_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  340.         $TempHash += $unused_user_accounts_obj 
  341.         Write-Verbose "User $($row.LoginName) has no last login date - it has never been used" 
  342.     } 
  343.     return $TempHash 
  344. } # END FUNCTION get-UnusedAccounts 
  345.  
  346.  
  347. function get-UsrAccountsWithNoPasswordExpiry() 
  348. { 
  349.     $TempHash = @() 
  350.     $ObjProps = @() 
  351.     $guawnpeQuery = "SELECT LoginName FROM virtualuser WHERE passwordExpireInterval IS NULL" 
  352.     $guawnpeResults = run-MySQLQuery -connectionString $connString -query $guawnpeQuery 
  353.      
  354.     if( $guawnpeResults -eq $null ) 
  355.     { 
  356.         $ObjProps = @{'Name'='no users found'; 
  357.             'Email'='-';} 
  358.         $no_passwd_expiry_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  359.         $TempHash += $no_passwd_expiry_user_accounts_obj 
  360.         return $TempHash 
  361.     } 
  362.      
  363.     foreach ( $row in $guawnpeResults ) 
  364.     { 
  365.         $email = get-UserEmail $row.LoginName 
  366.          
  367.         $ObjProps = @{'Name'=$row.LoginName; 
  368.             'Email'=$email;} 
  369.         $no_passwd_expiry_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  370.         $TempHash += $no_passwd_expiry_user_accounts_obj 
  371.         Write-Verbose "User $($row.LoginName) has no password expiry date set" 
  372.     } 
  373.     return $TempHash 
  374. } # END FUNCTION get-UsrAccountsWithNoPasswordExpiry 
  375.  
  376.  
  377. function get-AccountsNotUsedinXDays($days) 
  378. { 
  379.     $TempHash = @() 
  380.     $ObjProps = @() 
  381.     $timeinseconds = $days * 86400 
  382.     $ganuixdQuery = "SELECT LoginName, LastLogin FROM virtualuser WHERE LastLogin > (UNIX_TIMESTAMP(NOW()) - $timeinseconds)" 
  383.     $ganuixdResults = run-MySQLQuery -connectionString $connString -query $ganuixdQuery 
  384.      
  385.     if( $ganuixdResults -eq $null ) 
  386.     { 
  387.         $ObjProps = @{'Name'='no users found'; 
  388.             'Email'='-'; 
  389.             'LastLogin'='-';} 
  390.         $no_login_in_x_days_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  391.         $TempHash += $no_login_in_x_days_user_accounts_obj 
  392.         return $TempHash 
  393.     } 
  394.      
  395.     foreach ( $row in $ganuixdResults ) 
  396.     { 
  397.         $email = get-UserEmail $row.LoginName 
  398.          
  399.         $ObjProps = @{'Name'=$row.LoginName; 
  400.             'Email'=$email; 
  401.             'LastLogin'=$row.LastLogin;} 
  402.         $no_login_in_x_days_user_accounts_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  403.         $TempHash += $no_login_in_x_days_user_accounts_obj 
  404.         Write-Verbose "User $($row.LoginName) has not been used in $days days" 
  405.     } 
  406.     return $TempHash 
  407. } #END FUNCTION get-AccountsNotUsedinXDays 
  408.  
  409.  
  410. function get-ExpiringUserAccounts() 
  411. { 
  412.     $TempHash =@() 
  413.     $ObjProps = @() 
  414.     $virtualUserTableQuery = "SELECT LoginName, passwordExpireInterval, LastLogin FROM virtualuser" 
  415.     $results = run-MySQLQuery -connectionString $connString -query $virtualUserTableQuery    
  416.      
  417.     if( $results -eq $null ) 
  418.     { 
  419.         $ObjProps = @{'Name'='no users found'; 
  420.                         'Email'='-'; 
  421.                         'LastLogin'='-'; 
  422.                         'Days to Password Expiry'='-'} 
  423.         $expiring_passwd_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  424.         $TempHash += $expiring_passwd_obj 
  425.         return $TempHash 
  426.     } 
  427.      
  428.     foreach ( $row in $results) 
  429.     { 
  430.         if (is-null $row.LastLogin) 
  431.         { 
  432.             Write-Verbose "No LastLogin date for user: $($row.LoginName), the user has never logged in. Skipping user." 
  433.         }  
  434.         else  
  435.         {                
  436.              if (is-null $row.passwordExpireInterval) 
  437.              { 
  438.                 Write-Verbose "The password is not set to expire for user: $($row.LoginName)" 
  439.              }  
  440.              else 
  441.              { 
  442.                 $culture = New-Object system.globalization.cultureinfo("en-GB") 
  443.                 $LastLoginDate = Get-Date -Format ($culture.DateTimeFormat.ToLongDateString) -Date $row.LastLogin 
  444.                 $mail = get-UserEmail $row.LoginName 
  445.              
  446.                 # Check how many days are left to expiry (negative values indicate the password has already expired!) 
  447.                 $days_to_expiry = ($LastLoginDate.AddDays($row.passwordExpireInterval) - $LastLoginDate).Days 
  448.                  
  449.                 if ( $days_to_expiry -lt $passwd_expiry_threshold ) 
  450.                 { 
  451.                     $mail = get-UserEmail $row.LoginName                   
  452.                     $ObjProps = @{'Name'=$row.LoginName; 
  453.                         'Email'=$mail; 
  454.                         'LastLogin'=$LastLoginDate; 
  455.                         'Days to Password Expiry'=$days_to_expiry} 
  456.                     $expiring_passwd_obj = New-Object –TypeName PSObject –Prop $ObjProps 
  457.                     $TempHash += $expiring_passwd_obj 
  458.                     Write-Verbose "User $($row.LoginName), password is expiring in: $days_to_expiry days" 
  459.                      
  460.                     if ( -not $SkipUserNotification ) { notify-User $expiring_passwd_obj    } 
  461.                 } 
  462.              }    
  463.         } 
  464.         #Write-Verbose "" 
  465.     } # END FOR LOOP     
  466.     return $TempHash 
  467. } # END FUNCTION get-ExpiringUserAccounts 
  468.  
  469.  
  470. function get-AdminAccStatus() 
  471. { 
  472.     $TempHash = @() 
  473.     $AdminTableQuery = "SELECT name, lastPasswordChangeTime, lastLoginTime, isChangePassword FROM administrator" 
  474.     $results = run-MySQLQuery -connectionString $connString -query $AdminTableQuery 
  475.      
  476.     if( $results -eq $null ) 
  477.     { 
  478.         $props = @{'Name'='no users found'; 
  479.                    'Last Login Date'='-'; 
  480.                    'Last Password Change Date'='-'; 
  481.                    'Account Status'='-'; 
  482.                    'Password Expires in _ Days'='-'; 
  483.                    } 
  484.         $account_obj = New-Object –TypeName PSObject –Prop $props 
  485.         $TempHash += $account_obj 
  486.         return $TempHash 
  487.     } 
  488.      
  489.     foreach( $row in $results ) 
  490.     { 
  491.         $culture = New-Object system.globalization.cultureinfo("en-GB") 
  492.          
  493.         $lldisNull = $lpcdisNull = $FALSE; 
  494.         if (is-null $row.lastLoginTime)  
  495.         {  
  496.             [string] $AdminLastLoginDate = "never" 
  497.             $lldisNull=$TRUE  
  498.         } 
  499.         else   
  500.         {  
  501.             $row.lastLoginTime -match "(?<xday>\d{2})\/(?<xmonth>\d{2})\/(?<xyear>\d{4})(.*)" | Out-Null 
  502.             [system.datetime] $AdminLastLoginDate =   Get-Date -Month $matches.xday -Day $matches.xmonth -Year $matches.xyear        
  503.         } 
  504.          
  505.         if (is-null $row.lastPasswordChangeTime)  
  506.         {  
  507.             [string] $LastPasswordChangeDate = "never" 
  508.             $lpcdisNull=$TRUE  
  509.         } 
  510.         else  
  511.         {  
  512.             $row.lastPasswordChangeTime -match "(?<xday>\d{2})\/(?<xmonth>\d{2})\/(?<xyear>\d{4})(.*)" | Out-Null 
  513.             [system.datetime] $LastPasswordChangeDate =   Get-Date -Month $matches.xday -Day $matches.xmonth -Year $matches.xyear 
  514.         }     
  515.          
  516.         if (   (-not $lldisNull)  -and (-not $lpcdisNull) ) 
  517.         { 
  518.             if ( $admin_password_expiry -eq $null ) 
  519.             { 
  520.                 # Check how many days are left to expiry (negative values indicate the password has already expired!) 
  521.                 $daysToAdd = [int] $admin_password_expiry 
  522.                  
  523.                 $DaysToExpiry = ( $LastPasswordChangeDate.AddDays($daysToAdd) - $LastPasswordChangeDate ).Days 
  524.                  
  525.                 Write-Debug "Admin account, $($row.name), expiring in $DaysToExpiry days" 
  526.                  
  527.                 if ( $DaysToExpiry -lt $passwd_expiry_threshold ) 
  528.                 { 
  529.                     Write-Debug "Admin password for $($row.name) is due to expire soon." 
  530.                 } 
  531.             } 
  532.             else 
  533.             { 
  534.                 $DaysToExpiry = '-' 
  535.             } 
  536.         } 
  537.         else 
  538.         { 
  539.             $DaysToExpiry = '-' 
  540.         } 
  541.              
  542.         if( $row.isChangePassword -eq 0) { $AccountStatus = "Active" } 
  543.         elseif ( $row.isChangePassword -eq 1) { $AccountStatus = "Disabled" } 
  544.          
  545.         $props = @{'Name'=$row.name; 
  546.                    'Last Login Date'=$AdminLastLoginDate; 
  547.                    'Last Password Change Date'=$LastPasswordChangeDate; 
  548.                    'Account Status'=$AccountStatus; 
  549.                    'Password Expires in _ Days'=$DaysToExpiry; 
  550.                    } 
  551.         $account_obj = New-Object –TypeName PSObject –Prop $props 
  552.                  
  553.         $TempHash += $account_obj      
  554.          
  555.         #Write-Debug "" 
  556.          
  557.     } # END FOR LOOP 
  558.     return $TempHash 
  559. } # END FUNCTION get-AdminAccStatus 
  560.  
  561. ########################## 
  562. # END FUNCTION DEFINITIONS 
  563. ########################## 
  564.  
  565.  
  566.          
  567. ########################## 
  568. # BEGIN MAIN SCRIPT LOGIC 
  569. ########################## 
  570.  
  571. Write-Output "" 
  572. Write-Output "Starting user account audit script run at: $(Get-Date)"  
  573.  
  574. $LoadAssembly = [System.Reflection.Assembly]::LoadWithPartialName("MySql.Data") 
  575.  
  576. if ( -not $LoadAssembly )  
  577.  
  578.     throw "Error! Assembly not found {MySql.Data}. Script execution will be halted." 
  579.     exit 1 
  580. } 
  581.  
  582. Write-Output "" 
  583. Write-Output "Report will be written to $ReportFile" 
  584. Write-Output "" 
  585.  
  586. # Only the internal SecureTransport Server holds user accounts 
  587. if ($servername -contains $InternalSTServer) 
  588. { 
  589.     $NoPasswordExpirySetAccountsHash = get-UsrAccountsWithNoPasswordExpiry 
  590.     $UnusedUserAccountsHash = get-UnusedAccounts 
  591.     $DisabledUserAccountsHash = get-DisabledAccounts  
  592.     $NoLoginInXDaysAccountsHash = get-AccountsNotUsedinXDays $unusedThreshold  
  593. } 
  594. $ExpUserPassHash = get-ExpiringUserAccounts 
  595.  
  596. $AdminAccStatus = get-AdminAccStatus 
  597.  
  598.  
  599. ############################## 
  600. # BEGIN HTML REPORT GENERATION 
  601. ############################## 
  602.  
  603. $head = @'  
  604. <title>SecureTransport Account Status Report</title>  
  605. <style>  
  606. body { background-color:#dddddd;  
  607.        font-family:Verdana;  
  608.        font-size:12pt; }  
  609. td, th { border:1px solid black;  
  610.          border-collapse:collapse; }  
  611. th { color:white;  
  612.      background-color:black; }  
  613. table, tr, td, th { padding: 2px; margin: 0px }  
  614. table { margin-left:50px; }  
  615. a:link, a:visited { color: #6600ff; text-decoration:none;}  
  616. a:hover  { color: #ff4b33; text-decoration:underline;}  
  617. table {   
  618.     font-family: Verdana;   
  619.     border-style: dashed;   
  620.     border-width: 1px;   
  621.     border-color: #FF6600;   
  622.     padding: 5px;   
  623.     background-color: #FFFFCC;   
  624.     table-layout: auto;   
  625.     text-align: center;   
  626.     font-size: 10pt;   
  627. }   
  628. table th {   
  629.     border-bottom-style: solid;   
  630.     border-bottom-width: 1px;   
  631. }   
  632. table td {   
  633.     border-top-style: solid;   
  634.     border-top-width: 1px;   
  635. }   
  636. </style>  
  637. '@ 
  638.  
  639. $rundate = Get-Date 
  640.  
  641. $precontent = @" 
  642. <h1>SecureTransport Account Status Report</h1> 
  643. <br /> 
  644. <table> 
  645. <tr><th>Computername</th><td>$($servername)</td></tr> 
  646. <tr><th style="text-align:left">Run Date</th><td>$($rundate)</td></tr> 
  647. </table> 
  648. <br /> 
  649. "@ 
  650.  
  651.  #insert navigation bookmarks 
  652. $nav=@" 
  653. <br /><br /> 
  654. <a href='#userpe'>User Password Expiry</a>  
  655. <a href='#dua'>Disabled User Accounts</a>  
  656. <a href='#usernpe'>User Accounts with no Password Expiry Date</a>  
  657. <a href='#uuacc'>Unused User Accounts</a>  
  658. <a href='#nlixd'>Accounts Unused in $unusedThreshold days</a>  
  659. <a href='#adminaccinfo'>Admin Account Information</a>  
  660. <br /><br />  
  661. "@ 
  662.  
  663. $userpe=@"  
  664. <H2><a name='userpe'>User Password Expiry</a></H2> 
  665. <br /> 
  666. <p>The table below lists user accounts that are due to expire in $($passwd_expiry_threshold) days or less</p> 
  667. "@ 
  668. $dua=@" 
  669. <H2><a name='dua'>Disabled User Accounts</a></H2> 
  670. <br /> 
  671. <p>The table below lists user accounts that have been disabled</p> 
  672. "@ 
  673. $usernpe=@" 
  674. <H2><a name='usernpe'>User Accounts with no Password Expiry Date</a></H2> 
  675. <br /> 
  676. <p>The table below lists user accounts that do not have a password expiry date (i.e. the password never expires)</p> 
  677. "@ 
  678. $uuacc=@" 
  679. <H2><a name='uuacc'>Unused User Accounts</a></H2> 
  680. <br /> 
  681. <p>The table below lists the accounts where the user has never logged in.</p> 
  682. "@ 
  683. $nlixd=@" 
  684. <H2><a name='nlixd'>Accounts Not Used in the Last $unusedThreshold days</a></H2> 
  685. <br /> 
  686. <p>The table below lists the accounts where the user has not logged in $unusedThreshold days </p> 
  687. "@ 
  688. $adminaccinfo=@" 
  689. <H2><a name='adminaccinfo'>Admin Account Information</a></H2>  
  690. <br />  
  691. <p>The table below provides information on administrative accounts. The account expired column indicates whether the account has been expired (i.e. locked out via the administrative interface).</p>  
  692. "@ 
  693.  
  694. Write-Output " " 
  695. Write-Output "Generating HTML report" 
  696. Write-Output " " 
  697.  
  698.  
  699. if ($servername -contains $InternalSTServer) 
  700. { 
  701. $fraghash+=$nav 
  702. $fraghash += $ExpUserPassHash | ConvertTo-Html -As Table -Fragment -PreContent $userpe | Out-String 
  703. $fraghash+=$nav 
  704. $fraghash += $DisabledUserAccountsHash  | ConvertTo-Html -As Table -Fragment -PreContent $dua | Out-String 
  705. $fraghash+=$nav 
  706. $fraghash += $NoPasswordExpirySetAccountsHash | ConvertTo-Html -As Table -Fragment -PreContent $usernpe | Out-String 
  707. $fraghash+=$nav 
  708. $fraghash += $UnusedUserAccountsHash | ConvertTo-Html -As Table -Fragment -PreContent $uuacc | Out-String 
  709. $fraghash+=$nav 
  710. $fraghash += $NoLoginInXDaysAccountsHash | ConvertTo-Html -As Table -Fragment -PreContent $nlixd | Out-String 
  711. $fraghash+=$nav 
  712. } 
  713. $fraghash += $AdminAccStatus | ConvertTo-Html -As Table -Fragment -PreContent $adminaccinfo | Out-String 
  714.  
  715. if ($servername -contains $InternalSTServer) 
  716. { 
  717.     $fraghash+=$nav 
  718. } 
  719. ConvertTo-HTML -head $head -PostContent $fraghash -PreContent $precontent > $ReportFile 
  720.  
  721. Write-Output "Sending audit report via email" 
  722. send-Report 
  723. Write-Output " " 
  724.  
  725. ############################ 
  726. # END HTML REPORT GENERATION 
  727. ############################ 
  728.  
  729. Write-Output " " 
  730. Write-Output "Script finished and report produced at $(Get-Date)" 
  731. Write-Output " "  
  732.   
  733. $fraghash = $null  
  734. $ExpUserPassHash = $null  
  735. $DisabledUserAccountsHash = $null  
  736. $NoPasswordExpirySetAccountsHash = $null  
  737. $UnusedUserAccountsHash = $null  
  738. $NoLoginInXDaysAccountsHash = $null  
  739. $AdminAccStatus = $null  
  740.   
  741. [GC]::Collect()  
  742.   
  743.   
  744. ##########################  
  745. # END MAIN SCRIPT LOGIC  
  746. ##########################  

Comments