当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 解析 netlogon.log 以查找丢失的子网

作者:精品下载站 日期:2024-12-14 07:15:50 浏览:15 分类:玩电脑

使用 PowerShell 解析 netlogon.log 以查找丢失的子网


Active Directory 使用站点来定义计算机在拓扑中的位置,从而确定应将哪个服务器用于某些服务。例如,站点用于确定客户端应使用哪个域控制器作为登录服务器,如果我的一个客户端在澳大利亚某个站点登录,我可能不希望它处理来自美国域控制器的组策略。

因此,我们在 Active Directory 中定义站点,其中每个站点都与一个或多个子网关联,并且生活良好。但是,如果我们忘记定义某个子网或者突然使用一个新的子网,会发生什么情况呢?如果计算机在未分配站点的情况下连接到 Active Directory,则可能会导致意外行为。

有关此过程的更多详细信息,请访问以下链接:http://jorgequestforknowledge.wordpress.com/2011/01/27/dc-locator-what-does-quot-no-client-site- quot-netlogon-log 中的平均值/

让任何未定义子网中的计算机使用默认站点的一个好方法是使用“catch-all”子网。如果一台计算机的 IP 地址与多个子网匹配,则最具体的匹配获胜,这意味着我可以将 10.1.1.0/24 分配给 Site1,将 10.1.2.0/24 分配给 Site2,然后将 10.1.0.0/16 分配给 Site1,从而生成任意地址在此范围内,与任何其他定义的子网不匹配的子网将与 Site1 关联。

然而,这篇文章并不是关于为什么、是否或如何定义子网的问题。它是关于查找客户端使用哪些子网而未在 Active Directory 中定义的子网。要找到这些子网(从现在开始称为“丢失的子网”),我们需要检查每个域控制器上的 netlogon.log 并查找错误消息 NO_CLIENT_SITE 。

该行的第一部分将是时间戳(如果未禁用时间戳),客户端计算机的名称和 IP 地址将列在该行的最后。在大型环境中这可能是一项相当繁琐的任务,因此我编写了一个脚本来从多个域控制器收集 netlogon.log 日志的最后部分并搜索 NO_CLIENT_SITE。它还将从每行中提取时间戳、计算机名称和 IP 地址,并将其作为自定义 PSObject 返回,以便于排序和/或过滤。如果由于任何原因在任何域控制器上禁用了 netlogon.log 的时间戳,请将参数 -IncludeTimestamp 设置为 $false)。该脚本非常简单,我使用以下代码枚举当前域中的所有域控制器作为 -DomainControllers 的默认值:

([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).DomainControllers.Name

然后我编写了两个函数,第一个函数使用带有参数 -Tail 的 Get-Content 从每个域控制器的 netlogon.log 日志文件中检索最后 (n) 行,并将每一行发送到管道。

第二个函数接受来自管道的字符串。在此函数中,我首先根据参数 IncludeTimestamp 在 Begin{} 块中定义了一个正则表达式。然后将该模式与分析的每一行进行匹配。为了从与我的模式匹配的每一行中提取我感兴趣的信息,我使用了名为命名组的东西。简而言之,正则表达式中括号内的任何内容都被视为一个组,并且在 PowerShell 中使用 -match 运算符时将填充到自动变量 $matches 中。

然后可以使用 $matches[index] 访问每个组,其中 index 是从 1 开始的组的索引号。$Matches[0] 将始终包含整个匹配的字符串。然而,跟踪每个组的索引很快就会变得非常令人沮丧,特别是如果您有嵌套组。对于这个问题有一个很好的解决方案,称为命名组。

只需在第一个括号后输入“?”,即可使用组名作为索引来提取组。让我们举个例子。

一组人被要求用五句话来展示自己。我们假设每个人都会写下自己的名字,并且可能会加上“name is”前缀。让我们将每个句子与一个模式相匹配。

$Pattern = “name is (?<name>w+)”

这将搜索“name is”,后跟 w,它是任何字母数字字符或下划线的正则表达式,以及 +,意味着字母数字字符(或下划线)将出现一次或多次。括号内的匹配部分是一个名为“name”的组。

现在匹配一个句子可能如下所示:

”My name is Simon” -match $Pattern

这将返回 True 并填充自动变量 $matches。通过将 $matches 传递给 Get-Member 来检查 $matches 将显示 $matches 是一个哈希表。要从匹配的句子中提取命名组,我们可以简单地从哈希表中获取键“name”的值:

$Matches[“name”]

匹配完成后,通过创建 PSCustomObject 并将其写入输出来返回结果。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯