我如何合理地获取Windows 7用户的用户名,但如果它存储在Active Directory域中(例如BillyBird
),则不会使用用户在登录时输入的任何情况(可能是billybird
,但甚至可能是bILlYbIRd
)?
这是在Perl中,但由于它与操作系统交互,因此其他语言的解决方案可能是可翻译的。
我尝试过这些并且它们不起作用;在登录*:
时,用户输入的用户名都会返回用户名getlogin
Win32::LoginName
$ENV{USERNAME}
Win32::OLE->new('WScript.Network')->UserName
Win32API::Net::UserGetInfo
我想出了几种获得正确价值的坏方法。我会将这些作为答案发布,并希望其他人有更好的答案。感谢。
*至少他们有时会这样做。对于某些用户,每次他们在给出as-typed和as-AD值之间登录时都会交替,但在所有情况下,上述方法都彼此一致并%USERNAME%
。
答案 0 :(得分:0)
这得到正确的值,但涉及通过网络获取所有域用户的列表并迭代它们寻找不区分大小写的匹配,这似乎过于仅仅返回当前用户的内容:
use v5.16;
use Win32::NetAdmin qw<GetDomainController GetUsers FILTER_NORMAL_ACCOUNT>;
my $comparable_username = fc getlogin;
GetDomainController('', '', my $domain_controller);
GetUsers($domain_controller, FILTER_NORMAL_ACCOUNT, \my @all_username);
my $username;
for (@all_username)
{
if (fc eq $comparable_username)
{
$username = $_;
last;
}
}
答案 1 :(得分:0)
以下是关于使用wmic
付诸实践的想法
use strict;
use warnings 'all';
say username();
sub username {
for ( `wmic useraccount get name` ) {
return $1 if /\A($ENV{USERNAME})\s*\z/i;
}
return;
}
要阻止wmic
获取完整的用户名列表,您可以在LIKE
cal
WHERE
运算符
sub username {
my @user = `wmic UserAccount WHERE ( name LIKE '$ENV{username}' ) GET name`;
return unless $user[1] =~ /\S/;
$user[1] =~ s/\s+\z//r;
}
答案 2 :(得分:-1)
这是一种可能的解决方案;它在正确的情况下获得用户名:
use IPC::System::Simple qw<capturex>;
my $username;
foreach (capturex qw<NET USER /DOMAIN>, getlogin)
{
if (/^User name\s*(\S+)$/)
{
$username = $1;
last;
}
}
然而,它涉及运行外部系统命令来解析其输出(相对较慢),并依赖于该输出始终为英语。使用API直接查找NET USER
命令正在执行的操作的替代解决方案将优于此。