我正在创建一些用于活动目录管理的工具,但遇到了通过 powershell 搜索 AD 时 IP 地址未转换为主机名的问题。作为解决方法,我创建了这个 Resolve-Hostname 函数,如果我单独运行它,它就可以正常工作。一旦我将它放入我的整体脚本中并尝试调用它,它就不会将 IP 转换为主机名...
下面是我创建的函数
function Resolve-Hostname {
If ($Workstation -like "*.*.*.*") #Convert IP Address to Hostname
{
$NameHost = resolve-dnsname $Workstation | Select-Object -ExpandProperty NameHost -First 1
$Workstation = ($NameHost -Split {$_ -eq "."})[0]
}
} #close of create the Resolve-Hostname function
任何知道如何更好地实现这一点的人也可以随意参与,我绝不是专家。
我不确定我的问题出在哪里,所以我将从顶部开始,任何优化我的脚本的建议将不胜感激。
设置窗口的大小
$pshost = get-host
$pswindow = $pshost.ui.rawui
$newsize = $pswindow.windowsize
$newsize.height= 30
$newsize.width = 60
$pswindow.windowsize = $newsize
声明显示菜单和解析主机函数
#Create functions
function Show-Menu { #Create the Show-Menu function
param ([string]$Title = 'Admin Tools Menu') #Sets title
Clear-Host
Write-Host " "
Write-Host " "
Write-Host "`t$Title" -foregroundcolor Blue #Display title of menu
Write-Host "`t1: Add Admin."
Write-Host "`t2: Boot Time."
Write-Host "`t3: User 'Shr_' Groups."
Write-Host "`t4: Computer Management."
Write-Host "`t5: Active Directory."
Write-Host "`t6: Remove Admin."
Write-Host "`t7: Disable Workstation in AD"
Write-Host
Write-Host "`tQ: Enter 'Q' to quit."
Write-Host
Write-Host
} #close of create show menu function
function Resolve-Hostname {
If ($Workstation -like "*.*.*.*") #Convert IP Address to Hostname
{
$NameHost = resolve-dnsname $Workstation | Select-Object -ExpandProperty NameHost -First 1
$Workstation = ($NameHost -Split {$_ -eq "."})[0]
}
} #close of create the Resolve-Hostname function
#End of create functions
下面脚本的实现
#Begin Main Menu
do
{
Show-Menu #Displays created menu above
$Selection = $(Write-Host "`tMake your selection: " -foregroundcolor Red -nonewline; Read-Host)
switch ($selection)
{
'1' { #Add Admin
Clear-Host
$Workstation = $(Write-Host "Workstation\IP Address" -nonewline -foregroundcolor DarkGreen) + $(Write-Host "?: " -NoNewline; Read-Host) #Declare Workstation/IP Address
Resolve-Hostname
$Workstation
pause
暂停后,脚本将工作站添加到管理组,但我相当确定该部分与当前的问题无关。没有弹出任何错误,只是 $workstation 输出 IP 地址,而不是按照解析主机名函数解析为主机名。
您不能从scriptscope中从该作用域调用的函数内部直接修改存在于该作用域中的变量,因为它在child作用域中运行。
$script:
范围修饰符 -
$script:Workstation
,在您的情况下 -会工作,[1],或更一般地,
Set-Variable
-Scope 1 WorkStation ...
,跨范围边界访问变量是最好的为了封装而避免。
参数解析的值,以及 (b) 输出(可能)解析的值:
function Resolve-Hostname {
param(
[string] $Workstation # Declare a parameter.
)
# Note that $Workstation now refers to the (always local) *parameter* variable.
If ($Workstation -like "*.*.*.*") { #Convert IP Address to Hostname
$NameHost = Resolve-DnsName $Workstation | Select-Object -ExpandProperty NameHost -First 1
# Extract the first "."-based component *and output it*.
($NameHost -split '\.')[0]
} else {
$Workstation # Already a hostname, output it as-is.
}
}
然后您可以按如下方式调用您的函数:
# Sample value.
$workstation = '142.251.40.238'
# Call the function with the sample value, and capture the
# output in the same local variable.
$workstation = Resolve-HostName $workstation
[1] 原始问题和 $script:
解决方法的快速演示,使用脚本块 (
{ ... }
) 代替函数,通过调用运算符
&
进行调用,该函数在子范围:
$i = 42; & { $i = $i + 1 }; $i
输出
42
,因为
$i = ...
赋值隐式创建了local
$i
变量,因此父作用域中的原始
$i
变量保持不变。相比之下,
$i = 42; & { $script:i = $i + 1 }; $i
输出
43
,因为
$script:i = ...
明确针对脚本(父)范围的
$i
变量。