我试图在PowerShell登录脚本中获取域用户的用户名。任何数量的不同用户都可能登录到相关计算机。
在Win7 / Win8域客户端上配置本地用户帐户(让我们称之为“syscheck'”)以运行PS脚本(PS 2.0 / 3.0);该脚本驻留在本地,由任务计划程序在用户登录时启动。该脚本需要获取登录的域用户的用户名。
我试图用WMI做到这一点:
Get-WmiObject Win32_ComputerSystem | Select-Object -ExpandProperty UserName
但是当脚本运行时,这不会返回任何内容。
如果我试试这个:
$env:USERNAME
' syscheck'的用户名返回本地帐户。
当脚本在登录时运行时,域用户名是否仍然不可用?
也许有办法用.NET做到这一点?其他选择?
***** 8月8日更新*****
我已经使用提供的解决方案进行了测试(感谢Alexander!)但仍无法检索已登录用户的用户名。我相信这是因为,如上所述,这是Task Scheduler启动的登录脚本。启动脚本的Task的主体是本地帐户。出于某种原因,尝试获取域用户名的所有方法都失败了。
这是最新的尝试:
首先,这是我调用函数的方式:
$indx = 0
do {
$username = GetDomUser
if (($indx -eq 25) -or ($username.Length -ne 0)) {
Write-Output $username
Break
}
else {
Start-Sleep -Seconds 12
}
$indx++
}
while ($indx -lt 25) # 5 minutes is PLENTY of time for boot...
现在,这里的功能是:
Function GetDomUser {
$compname = $($env:COMPUTERNAME)
$pattern = '"MYDOMAIN",Name='
$antecedent = @(Get-WmiObject -Class Win32_LoggedOnUser -ComputerName $compname |
Where-Object { $_.Antecedent -match $pattern } | Select-Object -ExpandProperty Antecedent)
Return ([regex]::Match([string]$antecedent[0],"$pattern(.*$)").Value).Split('=')[1] -replace '"', ""
}
当然,一旦机器启动,这在控制台上完美运行。
是否可以刷新Win32_LoggedOnUser类从中获取数据的任何存储?
其他选择?
以下是我尝试过的方法 - 都返回启动脚本的Task的主体的用户名(或者是一个空字符串,这是D返回的内容)。
$usernameA = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
$usernameB = $(whoami)
$usernameC = $($env:USERNAME)
$usernameD = $(Get-WmiObject Win32_ComputerSystem -ComputerName $compname | Select-Object -ExpandProperty UserName)
$usernameE = $([Environment]::UserName)
答案 0 :(得分:0)
您可以采取哪些措施来了解正在发生的事情:
$iLOGON32_LOGON_INTERACTIVE = 2
$cLogonSessions = Get-WmiObject -Class "Win32_LogonSession" `
| Where-Object { $_.LogonType -eq $iLOGON32_LOGON_INTERACTIVE }
if ($cLogonSessions -ne $null) {
$cInteractiveLogons = @()
foreach ($oLogonSession in $cLogonSessions) {
$sWmiQuery = ('ASSOCIATORS OF {{Win32_LogonSession.LogonId="{0}"}} ' `
+ 'WHERE AssocClass=Win32_LoggedOnUser') -f $oLogonSession.LogonId
$cInteractiveLogons += Get-WMIObject -Query $sWmiQuery `
| Select-Object -ExpandProperty "Caption"
}
} else {
$ex = New-Object -TypeName System.NullReferenceException(`
'$cInteractiveLogons is null.')
throw $ex
}
$cInteractiveLogons | Select-Object -Unique
当抛出$cInterativeLogons is null
异常时,这意味着没有人以交互方式登录(在这种情况下)您可以等待并稍后重新检查。
请注意,此代码不可靠,因为LOGON32_LOGON_INTERACTIVE
并不仅限于XP和早期版本中的本地控制台登录。
至于实际解决方案,我建议使用某种显式通知。例如,您可以使用事件。订阅一个事件,然后从用户的常规登录脚本中发出事件。
答案 1 :(得分:0)
问题不在于WMI代码,而在于运行它的机器的状态。事实证明,当用户被VPN连接到他们的机器中时(几乎总是归功于VPN客户端的自动重新连接功能),或者安装了一些第三方实用程序(例如某些云备份服务),有多个登录和& #34;所述"登录用户不明确。
目前这种方法运作良好:
Function GetDomainUser {
$compname = $($env:COMPUTERNAME)
$pattern = '"' + $($env:USERDOMAIN) + '"' + ',Name='
$antecedent = @(Get-WmiObject -Class Win32_LoggedOnUser -ComputerName $compname |
Where-Object { $_.Antecedent -match $pattern } |
Select-Object -ExpandProperty Antecedent | Select-Object -Unique)
Return $(([regex]::Match([string]$antecedent,$($pattern + '(".+")')).Value).Split('=')[1] -replace '"','')
}
但是当我无法发现LoggedOnUser(存在多个登录)或没有人登录时,我必须编写附加代码来解决这些情况。