函数可以单独运行,但不能在脚本中运行

问题描述 投票:0回答:1

我正在创建一些用于活动目录管理的工具,但遇到了通过 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 地址,而不是按照解析主机名函数解析为主机名。

windows powershell active-directory
1个回答
3
投票
  • 您不能从scriptscope中从该作用域调用的函数内部直接修改存在于该作用域中的变量,因为它在child作用域中运行。

  • 使用

    $script:

     范围修饰符 - 
    $script:Workstation
    ,在您的情况下 - 
    工作,[1],或更一般地,Set-Variable
    -Scope 1 WorkStation ...
    ,跨范围边界访问变量是最好的为了封装而避免。

      相反,让你的函数
    • 输出(返回)修改后的值,并让调用者(重新)将输出分配给其范围内的变量。
    • 同样,函数最好通过
    • 声明的参数接收输入值作为参数
    • 这两种技术如下所示。

按如下方式重新定义您的函数,使其 (a) 接受要通过

参数解析的值,以及 (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
变量。

© www.soinside.com 2019 - 2024. All rights reserved.