PowerShell中计算机的NetBIOS域

20

如何从PowerShell获取当前计算机的NetBIOS(又称“短”)域名?

$ENV:USERDOMAIN显示当前用户的域,但我想知道当前计算机所属的域。

我发现你可以在VBScript中很容易地完成它,但显然ADSystemInfo在PowerShell中使用不太好

更新

这是我的最终解决方案,结合了使用Win32_NTDomain的建议,但过滤到当前机器的域

$wmiDomain = Get-WmiObject Win32_NTDomain -Filter "DnsForestName = '$( (Get-WmiObject Win32_ComputerSystem).Domain)'"
$domain = $wmiDomain.DomainName

对于那些在David的回答中获得多个域名的人,请参见https://dev59.com/mHvaa4cB1Zd3GeqPFZtE#21284636。 - JamesQMurphy
11个回答

21

在大多数情况下,默认的NetBIOS域名是DNS域名中最左侧的标签,直到第15个字节(NetBIOS名称的限制为15个字节)。

在安装Active Directory期间可能会更改NetBIOS域名,但无法更改它。

WIN32_ComputerSystem WMI对象提供有关Windows计算机的信息。

PS C:\> Get-WmiObject Win32_ComputerSystem

Domain              : WORKGROUP
Manufacturer        : Hewlett-Packard
Model               : HP EliteBook 8530w (XXXXXXXXX)
Name                : ABCHPP2
PrimaryOwnerName    : ABC
TotalPhysicalMemory : 4190388224

因此域名是由以下内容给出的:

PS C:\> (gwmi WIN32_ComputerSystem).Domain

在域安装中,给定了DNS名称。在这种情况下,你可以使用nbtstat -n命令查找显示为 <DOMAIN><1B> 的NetBIOS域名。

PowerShell命令可能是:

nbtstat -n | Select-String -Pattern "^ *(.*) *<1B>.*$" | % {$_ -replace '^ *(.*) *<1B>.*$','$1'}

以下是使用WMI的另一种方法:

PS C:\> (gwmi Win32_NTDomain).DomainName

我已经尝试过那种方法,但它不起作用。 'Domain' 属性不是我想要的短/NetBIOS名称。它包含完整的 AD 域名。 - David Gardiner
我尝试了这个,但我的显示的是<1E>(而不是<1B>)。 - Mike Shepard
根据文档,它可以是<00>、<1B>、<1C>、<1D>、<1E>,因此您可以将正则表达式更改为"^ (.) <1[BCDE]>.$"。 - JPBlanc
Win32_NTDomain WMI对象怎么样? - JPBlanc
那个在我的环境中看起来不错。我喜欢它比我给出的复杂答案好多了。 :-) - Mike Shepard
5
Win32_NTDomain 看起来很不错。请注意,它返回多个条目,包括本地计算机和可能存在的其他受信任的域(如果有)。 - David Gardiner

11

使用 env: 通过 PowerShell 获取环境设置。

NetBIOS: $env:userdomain

FQDN: $env:userdnsdomain

要查看所有值:

dir env:  (no $)

2
那个答案已经在我的问题中提到了。但它没有返回计算机的域名(这就是我所问的)。 - David Gardiner
USERDOMAINUSERDNSDOMAIN 两个变量。第二个变量适合我的任务。 - Andreas
谢谢!这就是我要找的答案。 - lesca

6
import-module activedirectory
(Get-ADDomain -Identity (Get-WmiObject Win32_ComputerSystem).Domain).NetBIOSName

4

来自这里

的内容:

# Retrieve Distinguished Name of current domain.
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Root = $Domain.GetDirectoryEntry()
$Base = ($Root.distinguishedName)

# Use the NameTranslate object.
$objTrans = New-Object -comObject "NameTranslate"
$objNT = $objTrans.GetType()

# Invoke the Init method to Initialize NameTranslate by locating
# the Global Catalog. Note the constant 3 is ADS_NAME_INITTYPE_GC.
$objNT.InvokeMember("Init", "InvokeMethod", $Null, $objTrans, (3, $Null))

# Use the Set method to specify the Distinguished Name of the current domain.
# Note the constant 1 is ADS_NAME_TYPE_1779.
$objNT.InvokeMember("Set", "InvokeMethod", $Null, $objTrans, (1, "$Base"))

# Use the Get method to retrieve the NetBIOS name of the current domain.
# Note the constant 3 is ADS_NAME_TYPE_NT4.
# The value retrieved includes a trailing backslash.
$strDomain = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $objTrans, 3)

FYI,我在Windows 10 20H2上的Windows PowerShell上尝试了这个操作,第一行代码执行失败并抛出异常信息:“Exception calling "GetCurrentDomain" with "0" argument(s): "Current security context is not associated with an Active Directory domain or forest."” - David Gardiner

3

OP是在“计算机域”之后,所以答案应该是$GetComputerDomain(下面),但我也会添加$GetUserDomain作为参考。

$GetComputerDomain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()).Name
$GetUserDomain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name

我发现wmi(gwmi)选项特别慢,尤其是在查询Win32_NTDomain类时。我有一个多信任域环境,在需要快速获取简单信息时就需要很长时间。


1
抱歉,那不是我想要的结果。它们都返回完整的DNS风格域名。我想要的是短/NetBIOS风格的域名。 - David Gardiner

2
使用 Active Directory 命令 Get-ADDomain:
(Get-ADDomain -Current LocalComputer).NetBIOSName

那看起来像是对 @Sacha 的回答的变体。 - David Gardiner
是的,它很相似。我的只是按键少一些 :) - Jez
哈!我猜你只有有限的次数可以使用 http://keysleft.com/ :-) - David Gardiner
天哪,希望我90岁时还不用工作!哈哈 - Jez

1

这里有一个比Win32_NTDomain更快的方法,用于获取计算机的NetBIOS域。

# Get the computer system CIM/WMI
$computersystem = Get-CimInstance Win32_ComputerSystem

# Create a Windows Identity Principal object based on the name and domain in Win32_ComputerSystem
$ComputerPrincipal = [System.Security.Principal.WindowsIdentity]::new("$($computersystem.name)@$($computersystem.domain)")

# Split the NetBIOS name on \ and get the first value which should be the domain
($ComputerPrincipal.Name -split "\\")[0]


# Bonus point, the WindowsIdentity Principal has a bunch of other useful information.
# Like quick enumeration of the groups it's in (but needs to be translated from SID to NTAccount format).
$ComputerPrincipal.Groups.Translate([System.Security.Principal.NTAccount]).value

1

使用ADSystemInfo COM对象应该可以工作,而且不会有Win32_NTDomain查找的延迟:

$ADSystemInfo = New-Object -ComObject "ADSystemInfo"
$ADSystemInfo.GetType().InvokeMember("DomainShortName", "GetProperty", $null, $ADSystemInfo, $null)

这个 COM 对象还提供了其他与 AD 相关的属性:

https://learn.microsoft.com/en-us/windows/win32/adsi/iadsadsysteminfo-property-methods

[编辑 - 最初包括WinNTSystemInfo COM对象的代码,但评论者指出这只返回用户的短域 - 但ADSystemInfo确实返回计算机的短域]


那看起来返回的是用户域,而不是机器域。 - David Gardiner
@DavidGardiner 今天已经检查过了,WinNTSystemInfo的DomainName属性确实返回用户所在的域,而不是计算机所在的域。但是ADSystemInfo的DomainShortName属性正如您所需。我已更新答案以反映这一点。 - Minkus

1

这也可以通过使用.NET框架来完成(它比WMI更快)

PS > [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()

将返回

HostName      : SurfaceBook
DomainName    : mydomain.com
NodeType      : Hybrid
DhcpScopeName :
IsWinsProxy   : False

0

使用 NetGetJoinInformation 和 P/Invoke:

Add-Type -MemberDefinition @"
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint NetApiBufferFree(IntPtr Buffer);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int NetGetJoinInformation(
  string server,
  out IntPtr NameBuffer,
  out int BufferType);
"@ -Namespace Win32Api -Name NetApi32

function GetDomainName {
  $pNameBuffer = [IntPtr]::Zero
  $joinStatus = 0
  $apiResult = [Win32Api.NetApi32]::NetGetJoinInformation(
    $null,               # lpServer
    [Ref] $pNameBuffer,  # lpNameBuffer
    [Ref] $joinStatus    # BufferType
  )
  if ( $apiResult -eq 0 ) {
    [Runtime.InteropServices.Marshal]::PtrToStringAuto($pNameBuffer)
    [Void] [Win32Api.NetApi32]::NetApiBufferFree($pNameBuffer)
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接