0 votes

As part of our PCI compliance, we need to create a report of all the user accounts that are expiring in the next 30 days and email that to a user who compiles the information.

I tried using the built-in account expiration notifier, but that sends individual emails.

I'm very new to PowerShell, so I'm not sure what I would need to do to build this - I know I can scour the web for PowerShell commands to build it in general, but I was hoping to utilize Adaxes to automate it.

Any assistance would be very much appreciated.

by (440 points)

1 Answer

0 votes
by (215k points)

Update 2018

Starting with Adaxes 2018.1 you can use the built-in Soon-to-expire user accounts report. By default, the report is located in container Report\All Reports\Users\Account Status.

Original

Hello,

You can generate the report you need using the following PowerShell script:

$numDays = 30 # TODO: modify me
$to = "%adm-InitiatorEmail%" # TODO: modify me

# Email message setings
$subject = "My Subject" # TODO: modify me
$htmlReportFirstPart = @"
<h1><b>Users whose accounts expire in the next $numDays days</b></h1><br/>
<table border="1">
    <tr>
        <th>Full name</th>
        <th>Logon name</th>
    </tr>
"@ # TODO: modify me

$htmlReportLastPart = @"
</table><br/>

<p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>
"@ # TODO: modify me

$accountExpiresDate = ((Get-Date).AddDays($numDays)).ToFileTime()
$currentDate = (Get-Date).ToFileTime()

# Search all users
$searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
$searcher.SearchParameters.PageSize = 500
$searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.SearchParameters.Filter = "(&(objectCategory=user)(accountExpires>=$currentDate)(accountExpires<=$accountExpiresDate))"
$searcher.VirtualRoot = $True

$result = $searcher.ExecuteSearch()
$users = $result.FetchAll()
$result.Dispose()

if ($users.Count -eq 0)
{
    return
}

foreach ($user in $users)
{
    $user = $Context.BindToObject($user.AdsPath)

    # Add user information to the report
    $htmlReportFirstPart += "<tr><td>" + $user.Get("cn") + "</td>"
    $htmlReportFirstPart += "<td>" + $user.Get("userPrincipalName") + "</td></tr>"
}

# Build message body in HTML
$htmlBody = $htmlReportFirstPart + $htmlReportLastPart

# Send mail to the initiator
$Context.SendMail($to, $subject, $NULL, $htmlBody)

In the script:

  • $numDays specifies the number of days, within which an account should expire to meet the condition,
  • $to specifies the email of the recipient of the report, In the sample script, it is set to %adm-InitiatorEmail% that will be substituted with the email of the user who invokes the script. If you want emails to be always sent to the same email, you need to specify the email explicitly.

This script can be used in a Custom Command to generate the report on demand or in a Scheduled Task to generate the report on a schedule. To create a Custom Command that launches this script:

  1. Create a new Custom Command.
  2. On the 2nd step of the Create Custom Command wizard, enable the Show all properties checkbox, and select the Domain-DNS object type.
  3. On the 3rd step, click the Add Action link and choose the Run a program or a PowerShell script action.
  4. Paste the script above in the Script field.
  5. Finish creation of the Custom Command.

When executed on a domain, the Custom Command will compose a report on all the users who meet the condition.

0

Great - that gets me most of it - however, I'd also like to include the date that the account expires on.

According to the web, I just need to update it like the below:

$numDays = 30
$to = "<email>"

# Email message setings
$subject = "INFORM: PCI Compliance Account Expiration Notice" 
$htmlReportFirstPart = @"
<h3><b>Users whose accounts expire in the next $numDays days</b></h3><br/>
<table border="1">
    <tr>
        <th>Full name</th>
        <th>Logon name</th>
    <th>Account Expiration Date</th>
    </tr>
"@ 

$htmlReportLastPart = @"
</table><br/>

<p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>
"@ 

$accountExpiresDate = ((Get-Date).AddDays($numDays)).ToFileTime()
$currentDate = (Get-Date).ToFileTime()

# Search all users
$searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
$searcher.SearchParameters.PageSize = 500
$searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.SearchParameters.Filter = "(&(objectCategory=user)(accountExpires>=$currentDate)(accountExpires<=$accountExpiresDate))"
$searcher.VirtualRoot = $True

$result = $searcher.ExecuteSearch()
$users = $result.FetchAll()
$result.Dispose()

if ($users.Count -eq 0)
{
    return
}

foreach ($user in $users)
{
    $user = $Context.BindToObject($user.AdsPath)

    # Add user information to the report
    $htmlReportFirstPart += "<tr><td>" + $user.Get("cn") + "</td>"
    $htmlReportFirstPart += "<td>" + $user.Get("userPrincipalName") + "</td>"
    $htmlReportFirstPart += "<td>" + [datetime]::FromFileTime($user.Get("accountExpires")) + "</td></tr>"
}

# Build message body in HTML
$htmlBody = $htmlReportFirstPart + $htmlReportLastPart

# Send mail to the initiator
$Context.SendMail($to, $subject, $NULL, $htmlBody)

Specifically:

    $htmlReportFirstPart += "<td>" + [datetime]::FromFileTime($user.Get("accountExpires")) + "</td></tr>"

However, when I run this code, it does not put in anything the the third column.

If I change it to

$htmlReportFirstPart += "<td>" + $user.Get("accountExpires") + "</td></tr>"

I get the "File Time" display - which isn't very helpful.

Is there a different set of code for changing the date back into an easily "readable" date format.

0

Hello,

The IADsUser interface that is supported by any user object has a property called AccountExpirationDate that returns the account expiration date in a human readable format. So, what you need to do is just to get the value for the property. Here's a modified version of the script that should do the job:

$numDays = 30 # TODO: modify me
$to = "<mail>" # TODO: modify me

# Email message setings
$subject = "INFORM: PCI Compliance Account Expiration Notice"
$htmlReportFirstPart = @"
<h3><b>Users whose accounts expire in the next $numDays days</b></h3><br/>
<table border="1">
    <tr>
        <th>Full name</th>
        <th>Logon name</th>
        <th>Account Expiration Date</th>
    </tr>
"@

$htmlReportLastPart = @"
</table><br/>

<p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>
"@

$accountExpiresDate = ((Get-Date).AddDays($numDays)).ToFileTime()
$currentDate = (Get-Date).ToFileTime()

# Search all users
$searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
$searcher.SearchParameters.PageSize = 500
$searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.SearchParameters.Filter = "(&(objectCategory=user)(accountExpires>=$currentDate)(accountExpires<=$accountExpiresDate))"
$searcher.VirtualRoot = $True

$result = $searcher.ExecuteSearch()
$users = $result.FetchAll()
$result.Dispose()

if ($users.Count -eq 0)
{
    return
}

foreach ($user in $users)
{
    $user = $Context.BindToObject($user.AdsPath)

    # Add user information to the report
    $htmlReportFirstPart += "<tr><td>" + $user.Get("cn") + "</td>"
    $htmlReportFirstPart += "<td>" + $user.Get("userPrincipalName") + "</td>"
    $htmlReportFirstPart += "<td>" + $user.AccountExpirationDate + "</td></tr>"
}

# Build message body in HTML
$htmlBody = $htmlReportFirstPart + $htmlReportLastPart

# Send mail to the initiator
$Context.SendMail($to, $subject, $NULL, $htmlBody)
0

Thank you, that did it.

I'll have to read up on the programming functions.

0

Take a look at Adaxes SDK, especially its Sample Scripts section. You'll find plenty of information there.

Related questions

0 votes
1 answer

We have four OUs in Active Directory (Pending Deletion, Disabled with Mail Delegates, Disabled with HR Extensions and Disabled_Temp_Leave) that users are moved to prior to their eventual ... past 7 days have been moved to one of 4 of these OUs. Thanks!

asked Jun 3, 2021 by RayBilyk (220 points)
0 votes
1 answer

I am trying to see if Adaxes and send me a report of how many users have Dial In access. is there a way to do it.. If so please advise .. The object is msNPAllowDialin

asked Dec 2, 2011 by Nate (20 points)
0 votes
1 answer

I need to be able to create a csv and email it once a week of accounts that have a date in %hiredate% that starts in the next 7 days. I need to include the full ... dept, and %hiredate% feilds in the CSV. Any help you can provide would be great. Thank you,

asked Sep 9, 2020 by hgletifer (1.3k points)
0 votes
1 answer

for example i add a form "create user for France" in the left pane, how can i translate it automatically when the UI in in French ? thank you

asked Apr 29, 2021 by GG (70 points)
0 votes
1 answer

Hi, Can you tell me how to look up a list of last logged-in users for computers from specific OU? Have OU called Laptops and need to know who as last person logged into ... username-of-last-user-who-lgged-on-to-computer-s269.htm but it' s not design for OU

asked Dec 2, 2019 by roberttryba (70 points)
2,803 questions
2,535 answers
6,605 comments
62,237 users