今天的日期和密码的有效期少于14天?

时间:2018-06-22 13:43:35

标签: powershell notifications passwords

我想确定来自多个域的所有用户,其中密码到期日期与今天的日期之间的差值应小于14天。稍后我想用powershell向所有用户写一封通知邮件。如何将内容从姓氏写入变量? 这是我给定的代码:

   
$datacoll =@()
$domains = "domain1","domain2","domain3"
$expindays = 14
$today = Get-Date
foreach($domain in $domains){

$datacoll += Get-ADUser -Server $domain -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
–Properties “SamAccountName”,”mail”,"GivenName","Surname",”pwdLastSet”,”msDS-UserPasswordExpiryTimeComputed” | where{$_.mail -ne $null} |
Select-Object -Property “SamAccountName”,”mail”,"GivenName","Surname",@{Name=”Password Last Set”;`
Expression={[datetime]::FromFileTime($_.”pwdLastSet”)}}, @{Name=”Password Expiry Date”;`
Expression={[datetime]::FromFileTime($_.”msDS-UserPasswordExpiryTimeComputed”)}} 
}
#iterate surname?
# foreach($user in $Surname){
# }

#datacoll output
$datacoll | Export-Csv "C:\pw.csv" -NoTypeInformation -Encoding utf8

3 个答案:

答案 0 :(得分:1)

您可以做的是使用.NET框架中的 DirectoryServices DirectoryServices.AccountManagement

您可以使用 system.reflection.assembly

加载这样的.Net程序集
[system.reflection.assembly]::LoadWithPartialName("System.DirectoryServices") | out-null

然后,您将创建一个域上下文(与AD的连接)和一个搜索器对象,该对象将通过该域查找用户对象。

我编写了一个函数,用于返回与范围(接近到期日期)和域相匹配的用户。然后它将返回一个目录条目数组,以便您可以获得所需的信息。

function Get-ADPasswordExpirationDates(){
    param(
        [Parameter(Mandatory=$True)]
        [string]$Domain,
        [int]$Range = 14
    )

    #Call .Net Active Directory Assembies
    [system.reflection.assembly]::LoadWithPartialName("System.DirectoryServices") | out-null
    [system.reflection.assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement") | out-null

    #Get Domain Context
    $Context = new-object System.DirectoryServices.AccountManagement.PrincipalContext(`
        [System.DirectoryServices.AccountManagement.ContextType]::Domain,`
        $domain
    )

    #Create Searcher Object looking for User Objects
    $Search = new-object System.DirectoryServices.AccountManagement.PrincipalSearcher(`
        new-object System.DirectoryServices.AccountManagement.UserPrincipal(`
            $Context
        )
    )

    #Arry Varable for holding return reply
    $Reply = @()

    #For Each User in search
    foreach($Result in $Search.FindAll()){
        #Turn Result into a Directory Entry 
        [System.DirectoryServices.DirectoryEntry] $Entry = $Result.GetUnderlyingObject()
        #Get Expiration Date
        $Expiration = $Entry.InvokeGet("PasswordExpirationDate")
        #Create a Timespan from Todays date to Expiration date
        $Timespan = $(New-TimeSpan -Start $(get-date) -End $Expiration).Days
        #If days are less then $RANGE add Directory Entry to array
        if($Timespan -lt $Range -and $Timespan -gt -1 ){
            $Reply += $Entry                                   
        }
    }
    return $Reply
}

这是如何使用它从目录对象获取信息的快速示例。

$AlmostExpiredUsers = Get-ADPasswordExpirationDates -domain MyAwesomeDomainName -Range 14
foreach($User in $AlmostExpiredUsers){
    Write-Output "Username : $($user.SamAccountName)`r`nFull Name : $($user.Properties.name)`r`nEmail : $($user.Properties.mail)`r`nExpires : $($user.InvokeGet("PasswordExpirationDate"))`r`n`r`n"
}

答案 1 :(得分:1)

我使用此脚本向用户发送有关密码过期的电子邮件

$MaxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

Get-ADUser -Filter * -SearchBase "OU=Admin user,DC=test,DC=test" -properties PasswordLastSet,
                                                                             PasswordExpired,
                                                                             PasswordNeverExpires,
                                                                             EmailAddress,
                                                                             DisplayName,
                                                                             GivenName,
                                                                             SN | 

foreach {

$UserName = $_.DisplayName
$SN = $_.SN
$Email = $_.EmailAddress
$today = Get-Date
$enc  = New-Object System.Text.utf8encoding
$ExpiryDate = $_.PasswordLastSet + $maxPasswordAgeTimeSpan
$DaysLeft = ($ExpiryDate-$today).days

If ($DaysLeft -lt 7 -and $DaysLeft -gt 0)
{
  Send-mailmessage -to  $Email -from noreply@noreply.com -Subject "enter subject" -body "enter body here" -smtpserver x.x.x.x -BodyAsHtml -Encoding $enc
 }

答案 2 :(得分:0)

这是一个最小的解决方案。 14天的时间跨度可以通过以下方式实现:

foreach($user in $datacoll){
    $StartDate=(Get-Date).Date
    $EndDate=([datetime] $user."Password Expiry Date").Date
    $diff = (New-TimeSpan -Start $StartDate -End $EndDate).Days
    $firstname = $user.GivenName
    $surname = $user.Surname
#body content in variable for parameter in Send-MailMessage 
    $body = @"
    Dear Sir or Madam,

    Your Password will expire in $diff days, 
    please change your password.

    Sincerely
    IT
    "@
    }

比起$diff变量,您可以使用if,else语句,并使用以下命令将邮件发送给所有用户:

if($diff -le 14){
Send-MailMessage -from "Helpdesk <helpdesk@noreply.com>" -to "$firstname $surname<$user.mail>" -subject "Password Expiration in $diff days" -smtp "smtpserver" -body $body
}

要检查多个域控制器,可以使用以下命令定义多个域控制器:

$dcs = "domaincontroller1","domaincontroller2","domaincontroller3"

包括一个foreach循环。 使用选项-Server,您可以传输参数$i,以从所有域控制器获得所有用户。 提示:您只能从根域控制器执行此脚本。

foreach($i in $dcs){    
$datacoll += Get-ADUser -Server $i -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and mail -like '*'} `
    –Properties “SamAccountName”,"GivenName","Surname",”mail”,”pwdLastSet”,”msDS-UserPasswordExpiryTimeComputed” |
    Select-Object -Property “SamAccountName”,"GivenName","Surname",”mail”,@{Name=”Password Last Set”;`
    Expression={[datetime]::FromFileTime($_.”pwdLastSet”)}}, @{Name=”Password Expiry Date”;`
    Expression={[datetime]::FromFileTime($_.”msDS-UserPasswordExpiryTimeComputed”)}}
    }
}