【问题标题】:Powershell Script to Disable Inactive AD Users Create Log and Send E-mail禁用非活动 AD 用户的 Powershell 脚本创建日志并发送电子邮件
【发布时间】:2014-08-08 17:48:12
【问题描述】:

一位同事联系我创建了一个 PowerShell 脚本来执行以下操作:

该脚本将读取名为“Temp Associates”的 AD 安全组的 lastlogondate,禁用 lastlogondate > 或 = 从当前日期起 29 天的帐户,然后移至 Disabled OU。当它禁用时,它还会将描述更改为禁用日期。然后创建一份列出禁用用户的报告并通过电子邮件发送给我们的全球帮助台。

我整理了一些看起来应该可以工作的东西,但实际上并没有。当我运行脚本时,我没有收到任何错误消息,并且生成的日志文件没有填充数据。为了保持 SOX 合规性,我应该能够操纵 $PasswordAge = (Get-Date).adddays(-29) 中的值以进行测试,因为我不确定我们目前是否有任何满足要求的帐户。

电子邮件现在可以工作了,只需要创建 PSCredential 以在 send-mailmessage -credential 参数中使用。

我是 PowerShell 的新手,可以使用我能获得的所有帮助。欢迎任何改进现有代码或使用不同方法的建议,但如果可能的话,我想利用我已有的。

代码如下:

#import the ActiveDirectory Module
Import-Module ActiveDirectory

#Create a variable for the date stamp in the log file
$LogDate = get-date -f yyyyMMddhhmm

#Sets the OU to do the base search for all user accounts, change for your env.
$SearchBase = "CN=Temp Associates,OU=Res Accounts,DC=our,DC=domain,DC=org"

#Create an empty array for the log file
$LogArray = @()

#Sets the number of days to disable user accounts based on lastlogontimestamp and pwdlastset.
$PasswordAge = (Get-Date).adddays(-29)

#Use ForEach to loop through all users with pwdlastset and lastlogontimestamp greater than date set. Also added users with no lastlogon date set. Disables the accounts and adds to log array.
#Add the properties you will be using to ensure they are available.
$DisabledUsers = (Get-ADUser -searchbase $SearchBase -Properties samaccountname, name, distinguishedname -filter {((lastlogondate -notlike "*") -OR (lastlogondate -le $Passwordage)) -AND (enabled -eq $True) -AND (whencreated -le $Passwordage)} )

if ($DisabledUsers -ne $null -and $DisabledUsers.Count > 0) {
    ForEach ($DisabledUser in $DisabledUsers) {

        #Sets the user objects description attribute to a date stamp. Example "11/13/2011"
        set-aduser $DisabledUser -Description ((get-date).toshortdatestring()) -whatif

        #Disabled user object. To log only add "-whatif"
        Disable-ADAccount $DisabledUser -whatif

        #Create new object for logging
        $obj = New-Object PSObject
        $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $DisabledUser.name
        $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DisabledUser.samaccountname
        $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DisabledUser.DistinguishedName
        $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Disabled'

        #Adds object to the log array
        $LogArray += $obj

    }

    # Move disabled users in Temp Associates group to Disabled OU 
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase “CN=Temp Associates,OU=Res Accounts,DC=our,DC=domain,DC=org”  | 
    Move-ADObject –TargetPath “OU=Disabled,DC=our,DC=domain,DC=org” -WhatIf

    #Exports log array to CSV file in the temp directory with a date and time stamp in the file name.
    $logArray | Export-Csv "C:\Temp\User_Report_$logDate.csv" -NoTypeInformation

    #Create PSCredential for use in e-mail -credential parameter
    $secpasswd = ConvertTo-SecureString "PasswordHere" -AsPlainText -Force
    $mycreds = New-Object System.Management.Automation.PSCredential ("UserHere", $secpasswd)

    #Send e-mail to Global Helpdesk with report generated
    $emailFrom = "smtp@address.com"
    $emailTo = "User@address.com" 
    $subject = "NA Disabled Temp Users to be deleted" 
    $smtpServer = "smtp.address.com"
    $attachment = "C:\Temp\User_Report_$logDate.csv"


    Send-MailMessage -To $emailTo -From $emailFrom -Subject $subject -SmtpServer $smtpServer -attachment $attachment -credential $mycreds
}else {
    Write-Output "No disabled users to process for $PasswordAge."

    #Create PSCredential for use in e-mail -credential parameter
    $secpasswd = ConvertTo-SecureString "PasswordHere" -AsPlainText -Force
    $mycreds = New-Object System.Management.Automation.PSCredential ("UserHere", $secpasswd)

    #Send e-mail to Global Helpdesk with report generated
    $emailFrom = "smtp@address.com"
    $emailTo = "User@address.com" 
    $subject = "NA Disabled Temp Users to be deleted" 
    $smtpServer = "smtp.address.com"
    $attachment = "C:\Temp\User_Report_$logDate.csv"
    Send-MailMessage -To $emailTo -From $emailFrom -Subject $subject -Body "No disabled users to process for $PasswordAge." -SmtpServer $smtpServer -credential $mycreds
}

【问题讨论】:

  • 这样测试账号就创建好了。我将 $PasswordAge = (Get-Date).adddays(-29) 更改为 $PasswordAge = (Get-Date).adddays(-1) 但仍然得到“禁止用户处理”。我将仔细研究过滤器,但一切看起来合乎逻辑。我不确定将 $searchbase 指定为组是否也存在问题。如果有人知道为什么即使我将 $Passwordage 降为 1 也不会产生任何结果,请告诉我。欢迎提出任何建议。
  • 有人有什么想法/建议吗?我有很短的时间来查看这个,但无法弄清楚我的逻辑在哪里搞砸了。感谢任何和所有的帮助。
  • 所以我有更多时间来解决这个问题,看起来问题是 $searchbase 要么不能正常工作,要么 Get-ADUser 命令不能正常工作。我试图在 $Searchbase 中指定的容器是一个安全组......我开始怀疑 Get-ADUser 是否不能与安全组一起使用?将继续努力解决并希望能解决问题。一如既往地感谢任何 cmets。

标签: email powershell active-directory user-inactivity


【解决方案1】:

把它作为一个答案,即使它不是一个直接的答案。

真的很难说哪里出了问题,尤其是当您在此过程中没有实施任何检查时。一个基本的调试策略是沿途添加一些输出,以查看脚本是否命中部分。例如:write-output "Entering Foreach"write-output "Looping user $($DisabledUser.samaccountname)" 以确保您的脚本正确执行。这将有助于确定您打嗝的位置。

或者,我首先要看的是您的Get-ADUser 查询。单独运行它并确保它返回用户。如果没有得到它返回预期结果的地方。

这是您的代码的修订版本,如果没有返回用户,它会进行错误检查。

#import the ActiveDirectory Module
Import-Module ActiveDirectory

#Create a variable for the date stamp in the log file
$LogDate = get-date -f yyyyMMddhhmm

#Sets the OU to do the base search for all user accounts, change for your env.
$SearchBase = "CN=Temp Associates,OU=Res Accounts,DC=our,DC=domain,DC=org"

#Create an empty array for the log file
$LogArray = @()

#Sets the number of days to disable user accounts based on lastlogontimestamp and pwdlastset.
$PasswordAge = (Get-Date).adddays(-29)

#Use ForEach to loop through all users with pwdlastset and lastlogontimestamp greater than date set. Also added users with no lastlogon date set. Disables the accounts and adds to log array.
#Add the properties you will be using to ensure they are available.
$DisabledUsers = (Get-ADUser -searchbase $SearchBase -Properties samaccountname, name, distinguishedname -filter {((lastlogondate -notlike "*") -OR (lastlogondate -le $Passwordage)) -AND (enabled -eq $True) -AND (whencreated -le $Passwordage)} )

if ($DisabledUsers -ne $null -and $DisabledUsers.Count > 0) {
    ForEach ($DisabledUser in $DisabledUsers) {

        #Sets the user objects description attribute to a date stamp. Example "11/13/2011"
        set-aduser $DisabledUser -Description ((get-date).toshortdatestring()) -whatif

        #Disabled user object. To log only add "-whatif"
        Disable-ADAccount $DisabledUser -whatif

        #Create new object for logging
        $obj = New-Object PSObject
        $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $DisabledUser.name
        $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DisabledUser.samaccountname
        $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DisabledUser.DistinguishedName
        $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Disabled'

        #Adds object to the log array
        $LogArray += $obj

    }

    # Move disabled users in Temp Associates group to Disabled OU 
    Search-ADAccount –AccountDisabled –UsersOnly –SearchBase “CN=Temp Associates,OU=Res Accounts,DC=our,DC=domain,DC=org”  | 
    Move-ADObject –TargetPath “OU=Disabled,DC=our,DC=domain,DC=org” -WhatIf

    #Exports log array to CSV file in the temp directory with a date and time stamp in the file name.
    $logArray | Export-Csv "C:\Temp\User_Report_$logDate.csv" -NoTypeInformation

    #Send e-mail to Global Helpdesk with report generated
    $emailFrom = "sender@mail.com" 
    $emailTo = "recipient@mail.com" 
    $subject = "NA Disabled Temp Users to be deleted" 
    $smtpServer = "smtp.server.com"
    $attachment = "C:\Temp\User_Report_$logDate.csv"


    Send-MailMessage -To $emailTo -From $emailFrom -Subject $subject -SmtpServer $smtpServer -attachment $attachment
}else {
    Write-Output "No disabled users to process for $PasswordAge."
}

【讨论】:

  • 中肯的建议。我倾向于使用write-verbose,它可以通过-verbose 开关启用或禁用额外的输出。
  • @andyb 是的,我通常也使用它,但在这样的脚本上下文中,我认为 -verbose 不起作用。它需要在带有[CmdletBinding()] 的函数内部。但是,如果我错了,请纠正我。
  • 它会起作用的。只需添加[CmdletBinding()] 和一个空的Param() 行。
  • 我以为我已经发布了回复,感谢您的快速回复,但我没有看到它。无论如何,再次感谢。我已经进行了您描述的更改以添加一些错误检查。我目前正在等待创建一个测试帐户,然后我会确定它是否功能齐全。感谢您详细而快速的回复。
【解决方案2】:

我发现if 中的代码永远不会被执行。 您必须将$DisabledUsers.Count > 0 替换为$DisabledUsers.Count -gt 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 2019-10-04
    • 2018-01-04
    相关资源
    最近更新 更多