PowerShell AD用户密码过期脚本更新版

越接触PowerShell感觉越喜欢这门脚本语言,简单易懂,功能强大,操作也方便,同时得益于微软的鼎力支持,在不同的微软产品平台都可以使用,如果想研究微软这方面的东西,会点PowerShell绝对是好处多多。

之前也写了一些关于PowerShell的文章,也相当于是自己不断摸索的过程,最近也陆陆续续写了一些脚本,有一些是工作环境里使用的,没办法拿出来分享,有一些是不同环境里都可以使用的,所以决定拿出来分享一下,脚本都很简单,写的也绝对算不上专业,只是基本的功能可以实现。

今天和大家分享的是写的一个比较简单的脚本,主要应用的场景也很常见,就是AD环境中,如果用户密码将要过期的话如何即使提醒用户即使更改密码,当然Windows会定期的自动提醒,这也是很多时候我们不需要这种脚本的一个原因,但是如果说是不同的环境呢?比如像我们常用的企业AD环境是公司的IT在运维,我们自己还会负责运维其他的AD环境,这些环境可能不会每天都登陆,甚至很长时间也不会登陆一次,这时候如果密码过期的话我们是看不到提醒的,所以这种情况下就很需要我们有这样一套密码过期提醒的机制来督促我们修改密码,同时如果是IT基础很薄弱的公司,我们还可以通过在邮件模板中加入修改密码方法的方式来告诉普通用户如何修改他们的密码,这样的话可以很大程度上减轻IT的负担。

这种类似的脚本实现的方法并不止一种,网上也有很多类似的脚本都可以实现这样的功能,但是这里要注意的一点是,有一些脚本因为写的年头比较久远了,之后微软在AD这方面又进行了一些更新,所以在一些比较新的环境里(比如Server 2012或者R2等)有些脚本可能就显得不会特别严谨,比如微软之前推出的颗粒化密码策略的功能,就有可能会导致对于密码过期时间的判断出现偏差。

这类脚本的实现方法基本都很简单,思路也都差不多,就是找出用户上次密码重置的时间,然后再加上允许密码最长的期限,这样算出来就是用户密码下一次的过期时间,但是如果是颗粒化密码策略的话实际上用户的允许密码最长期限就会不同于AD里的其他账户,在这一点上如果不注意,一视同仁的话那么就会导致最后的判断出现问题。

下边开始进入正题了,把脚本粘出来大家自己看一下就可以了,基本上都很简单

Function LogFile ($output, $initLog)
{
	if ($initLog -eq $True)
	{
		$input | out-file -filepath $output -encoding default -width 17384
	}
	else
	{
		$input | out-file -filepath $output -encoding default -width 17384 -append
	}
}

function Send-Report
{
	param($LogConent,$LogPath,$MailAddress)
	try
	{
		Send-MailMessage -From "[email protected]" -To $MailAddress -Subject ‘Contoso Password check report‘ -Body $LogConent -Priority ‘High‘ -SmtpServer mail.contoso.com -Port 25 -ErrorAction ‘SilentlyContinue‘
	}
	catch
	{
		$ErrorMessage = $Error[0].Exception.Message
		Write-Host -ForegroundColor ‘Red‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
		("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
	}
}

#Main Code
#Import ActiveDirectory module
Import-Module ActiveDirectory

#Log initialization
[string]$LogDate = Get-Date -Format "yyyyMMdd"
$LogPath = "C:\PasswordLogs\DomainPasswordLog$LogDate.txt"
if ((Test-Path ‘C:\PasswordLogs‘) -eq $false)
{
	New-Item -ItemType directory ‘C:\PasswordLogs‘ | Out-Null
}

#======================================================================================
#Get MaxPasswordAge
$RootDSE = Get-ADRootDSE
$PasswordPolicy = Get-ADObject $RootDSE.defaultNamingContext -Property maxPwdAge
$maxPwdAge = $PasswordPolicy.maxPwdAge/-864000000000
if (($maxPwdAge -eq 0) -or ($maxPwdAge -eq $null))
{
	$ErrorMessage = "MaxPasswordAge is not correct"
	Write-Host -ForegroundColor ‘Red‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
	("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
	$LogConent = Get-Content $LogPath -raw
	Send-Report -LogConent $LogConent -LogPath $LogPath -MailAddress ‘[email protected]‘
	exit
}
#======================================================================================
#Check userlist
#我这里的用户列表是写在一个txt文档里的,这是因为在我的环境中大部分用户是不需要这种邮件提醒的,他们的账户会由我们负责维护
#如果需要在AD里检索需要检查的用户的话可以直接这样写$userList=Get-ADUser -Filter *|Select-Object -ExpandProperty SamAccountName
#这样的话下边这段就不需要了
$userList = "C:\Users\abc\UserList.txt"
if ((Test-Path $UserList) -eq $false)
{
	$ErrorMessage = "Can‘t find userList.txt"
	Write-Host -ForegroundColor ‘Red‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
	("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
	$LogConent = Get-Content $LogPath -raw
	Send-Report -LogConent $LogConent -LogPath $LogPath -MailAddress ‘[email protected]‘
	exit
}

#======================================================================================

#这里如果是使用检索AD用户的方法的话可以直接写
#foreach($user in $userlist)替代get-content即可

Get-Content $UserList | %{
	$name = $null
	$userinfo = $null
	$ExpireDate = $null
	$PasswordSetDate = $null
	$Today = $null
	$leftDays = $null
	$body = $null
	$subject = $null
	$IndividualPasswordPolicy = $null
	$OutputMessage = $null
	$name = $_
	$userinfo = Get-ADUser -Identity $name -Properties *
    #这里首先判断该用户信息是否存在,如果不存在直接进行记录即可
	if ($userinfo -eq $null)
	{
		$ErrorMessage = $name + ": " + $Error[0].Exception.Message
		Write-Host -ForegroundColor ‘Red‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
		("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
	}
	else
	{
		if ($userinfo.PasswordNeverExpires -eq $true)
		{
		    #这里记录谁的密码被设置为永久不过期了
			$ErrorMessage = "$name‘s Password has been set to NeverExpires"
			Write-Host -ForegroundColor ‘Cyan‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
			("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
		}
		else
		{
			#这里会读取颗粒化密码策略的设置,它的优先级应该高于域策略的设置
			$IndividualPasswordPolicy = (Get-AduserResultantPasswordPolicy $name)
			if ($IndividualPasswordPolicy -ne $null)
			{
				$maxPwdAge = $IndividualPasswordPolicy.MaxPasswordAge.TotalDays
			}
			$PasswordSetDate = $userinfo.PasswordLastSet
			$ExpireDate = $PasswordSetDate.AddDays($maxPwdAge)
			$Today = Get-Date

			#对比过期时间和今天,得出的数值就是还有多少天过期
			$leftDays = (New-TimeSpan -Start $Today -End $ExpireDate).Days

			if ($leftDays -lt 0)
			{
				$body = "
    			Dear $name ,
   		 		<p> Your Password has expired!!.<br>
    			Please change your Password as soon as possible so that you can work normally<br>
   				<p>Thanks, <br> 
    			</P>"

				$subject = "Your Password has expired!!"
				$OutputMessage = "$(Get-Date -uFormat %Y%m%d-%H:%M:%S): $name‘s Password has expired"
				Write-Output $OutputMessage | LogFile -output $LogPath
			}
			elseif ($leftDays -eq 1)
			{
				$body = "
    			Dear $name ,
   		 		<p> Your Password will expire in <b><font size=`"20px`" color=`"red`"> $leftDays </font></b> Day!!.<br>
    			Please change your Password as soon as possible so that you can work normally <br>
   				<p>Thanks, <br> 
    			</P>"

				$subject = "Your Password will expire in $leftDays day!!"
				$OutputMessage = "$(Get-Date -uFormat %Y%m%d-%H:%M:%S): $name‘s Password will expire in $leftDays day"
				Write-Output $OutputMessage | LogFile -output $LogPath
			}
			elseif ($leftDays -le 10)
			{
				$body = "
    			Dear $name ,
   		 		<p> Your Password will expire in <b><font size=`"20px`" color=`"red`"> $leftDays </font></b> Days!!.<br>
    			Please change your Password as soon as possible so that you can work normally <br>
   				<p>Thanks, <br> 
    			</P>"

				$subject = "Your Password will expire in $leftDays days"
				$OutputMessage = "$(Get-Date -uFormat %Y%m%d-%H:%M:%S): $name‘s Password will expire in $leftDays days"
				Write-Output $OutputMessage | LogFile -output $LogPath
			}
			else
			{
				$OutputMessage = "$(Get-Date -uFormat %Y%m%d-%H:%M:%S): $name‘s Password will expire in $leftDays days"
				Write-Output $OutputMessage | LogFile -output $LogPath
			}

			#这里设置的是如果10天以内过期的话就会发送提醒
			if ($leftDays -le 10)
			{
			    #注意如果EmailAddress为空的话就需要自己处理如何找到邮件发送的地址了
				$MailAddress =   $userinfo.EmailAddress
				if ($MailAddress -ne $null)
				{
					try
					{
						Send-MailMessage -From "[email protected]" -To $MailAddress -Subject $subject -Body $body -BodyAsHtml -Priority ‘High‘ -SmtpServer mail.contoso.com -Port 25 -ErrorAction ‘SilentlyContinue‘
					}
					catch
					{
						$ErrorMessage = $Error[0].Exception.Message
						Write-Host -ForegroundColor ‘Red‘ "$(Get-Date -uFormat %Y%m%d-%H:%M:%S)" $ErrorMessage
						("$(Get-Date -uFormat %Y%m%d-%H:%M:%S): " + $ErrorMessage) | LogFile -output $LogPath
					}
				}

			}

		}

	}

}

#最后把这份报告发送给IT管理员
if ((Test-Path $LogPath) -eq $true)
{
	$LogConent = Get-Content $LogPath -Raw
	Send-Report -LogConent $LogConent -LogPath $LogPath -MailAddress ‘[email protected]‘
}

之后设置一个任务计划,每天运行这个脚本就可以了。

基本上功能就实现了,总体来说比较简单

时间: 2024-10-10 00:12:41

PowerShell AD用户密码过期脚本更新版的相关文章

Oracle用户密码过期问题解决

一.用户密码即将过期,导致autotrace无法打开           如果用户密码即将过期,在登录数据库时会收到如下提示:           ERROR:            ORA-28002: the password will expire within 7 days           当然,此时密码还未真正过期,用户在收到错误提示后依然可以登录数据库.但是,如果当收到密码即将过期的提示,想要开启autotrace就会有问题. SQL> conn darren/darren ER

web更改AD用户密码

#web更改AD密码 #网站配置 绑定域名ad.test.cn 功能,更改AD用户密码 #参考http://bbs.51cto.com/thread-1379675-1.html #安装IIS,勾选 脚本工具.ASP ##Ser2008 AD 添加web修改密码 #拷贝iisadmpwd如下目录 C:\Windows\SysWOW64\inetsrv #CMD窗口注册dll文件 regsvr32 C:\Windows\SysWOW64\inetsrv\iisadmpwd\iispwchg.dll

Oracle用户密码过期和用户被锁解决方法

[原因/触发因素] 确定是由于oracle11g中默认在default概要文件中设置了"PASSWORD_LIFE_TIME=180天"所导致. [影响和风险] 影响    密码过期后,业务进程连接数据库异常,影响业务使用.    问题发生频率    数据库密码过期后,业务进程一旦重启会提示连接失败. [解决方案] 按照如下步骤进行操作: 1.查看用户的proifle是哪个,一般是default: sql>SELECT username,PROFILE FROM dba_user

oracle 11g 用户密码过期问题解决

今天听同事讲到oracle密码过期问题,才想起来oracle 11g默认用户密码有效期为180天,oracle 10g默认用户密码为无期.oracle 11g用户密码过期会提示ORA-28001密码过期或ORA-28002密码将过期的错误.用户密码过期有可能导致应用连接出现问题,例如使用oracle 11g为数据库的vcenter,其vpx用户密码过期有可能导致vcenter服务无法运行: 解决oracle 11g用户密码过期的问题可以通过更改用户密码解决:alter user *** iden

通过JAVA开发的修改AD用户的工具,修改AD用户密码时报错

今天遇到1个用户反馈的问题,他们通过JAVA开发了一个工具(修改AD用户密码),在此工具中如果将LDAP指向1台辅助DC时就报错,详细信息如下: 问题描述: ========= 通过JAVA开发的修改AD用户密码的工具,LDAP指向1台辅助域控时,修改用户密码报错,JAVA上报错如下: javax.naming.CommunicationException: simple bind failed: 10.10.10.23:636 [Root exception is javax.net.ssl.

PowerShell批量修改AD用户密码属性

需求:非常普通的一个需求,就是给AD用户修改密码,但是问题是量太大了.所以写了个脚本 cls $pass = ConvertTo-SecureString -AsPlainText 12333333344.abc -Force Import-Csv -Path d:\pp.csv | foreach {  Get-ADUser -Identity $_.name|Set-ADAccountPassword -Reset -NewPassword $pass Get-ADUser -Identit

Oracle用户密码过期后重置SYS用户密码

问题状况: SYS.SYSTEM用户的密码过期,无法登陆. 运行EM控制台后,出现错误——ORA-28001: the password has expired (DBD ERROR: OCISessionBegin) 解决办法: 1.打开SQL PLUS,输入用户名sys/oracle as sysdba 2.执行脚本——alter user sys identified by oracle; 3.修改密码有效时间为永久——alter profile default limit passwor

11g oracle 用户密码过期问题

Oracle 11g 之前默认的用户时是没有密码过期的限制的,在Oracle 11g 中默认的profile启用了密码过期时间是180天.如下:select * from dba_profiles where profile='DEFAULT' and resource_name='PASSWORD_LIFE_TIME';过期的密码可用alter user userXXX identified by xxx;解决,可以修改为和以前一样. 如果想设置密码不过期,可用管理员登陆,然后执行: ALTE

Oracle查看用户密码过期,修改永不过期

01.查看当前open用户 select username,account_status,expiry_date,profile from dba_users; 02.查看目前的密码过期策略 select * from dba_profiles s where s.profile='DEFAULT' and resource_name='PASSWORD_LIFE_TIME'; 03.修改密码过期策略 alter profile default limit password_life_time