2012-11-09 68 views
3

所以,希望有人能幫助我。我在過去一直在尋找解決方案,並且總是找到一些東西。但這似乎太奇怪了。PowerShell中管道輸入的問題

我有一個PowerShell函數可以有效地複製New-ADUser Cmdlet,並且它接受多個參數才能這樣做。該函數的大部分參數都將「ValueFromPipelineByPropertyName」參數屬性設置爲True,以便我可以將CSV和其他管道數據輸入到函數中,而無需編寫大量「if」和賦值語句。或者至少是這個想法。

這裏是我的功能(slimed下降說明這一點更好)的例子:

[CmdletBinding()] 
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FirstName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$LastName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FullName 
) 

Process { 
    if(-not $FullName) { 
     $FullName = "$FirstName $LastName" 
    } 

    $user = "" | select FirstName,LastName,FullName 
    $user.FirstName = $FirstName 
    $user.LastName = $LastName 
    $user.FullName = $FullName 
    return $user 
} 

所以,當我跑這對CSV數據:

FirstName,LastName 
Bob,Smith 
Dick,Jones 
Sami,Davis 
Ray,Charles 
Jane,Doe 
Keith,Johnson 
Ruth,Willson 
Genni,Gartner 

我得到:

FirstName      LastName      FullName 
---------      --------      -------- 
Bob        Smith       Bob Smith 
Dick       Jones       Bob Smith 
Sami       Davis       Bob Smith 
Ray        Charles       Bob Smith 
Jane       Doe        Bob Smith 
Keith       Johnson       Bob Smith 
Ruth       Willson       Bob Smith 
Genni       Gartner       Bob Smith 

現在,我明白這裏發生了什麼。在管道輸入或函數參數中沒有FullName的指定值,所以我在process語句中設置了一個值,以便在該迭代中使用。問題是,代替$ FullName變量,然後將其重置爲null未定義的下一個循環迭代的值,它將保留值集。

如果我更改CSV數據以明確定義FullName的值,問題就會消失。但是當管道數據沒有定義屬性時,這並沒有幫助。

我試圖避免重新編碼全功能使用不同的變量名或使用$ _因爲添加到我也有參數的別名定義,這樣我們就可以直接拿數據的功能的複雜性我們HR程序的數據庫,並將其轉換爲新的用戶功能,而無需手動按摩數據。這也使我不能僅僅在管道數據中添加一個空值參數。

我知道我在我的解釋中有點冗長,但情景似乎是獨一無二的(至少根據我可以在互聯網上挖掘的內容)。

回答

1

這裏有些棘手的事情正在與variable scope進行,也許呢?

你可以嘗試在函數結尾添加一個Remove-Variable FullName,看看是否有幫助。

我知道你不想使用不同的變量名稱,但這可能會使事情變得更加清晰,以便使用不同的變量來將「生成的」全名存儲在函數中;希望這個範圍不會太雜亂。

if(-not $FullName) { 
    $GeneratedName = "$FirstName $LastName" 
} else { 
    $GeneratedName = $FullName 
} 
+0

呀,與同事集思廣益,我們能夠想出的唯一答案後確定_Begin_部分中的一個內部變量,用於捕獲任何直接定義的值。 –

0

爲什麼不能簡單地 '復位' 的$fullname變量?

[CmdletBinding()] 
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FirstName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$LastName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FullName 
) 

Process { 
      if([string]::IsNullOrEmpty($FullName)) 
       { 
        $script:Fullname = "$FirstName $LastName" 
       }   

    $user = "" | select FirstName,LastName,FullName 
    $user.FirstName = $FirstName 
    $user.LastName = $LastName 
    $user.FullName = $FullName 
    $FullName= [string]::Empty 
    $user 
} 
+0

該方法的問題在於,如果它在函數調用中被明確定義,它也會「重置」該值,這也不是很好。 –

+0

@ChrisDavis將'$ Fullname'的值賦給'$ user.Fullname'後不再是一個問題。在相同的流水線過程中,您可以訪問'$ user.FullName'來達到他的價值。 –

0

需要設置全名的默認值,所以下面的代碼將正常工作:

[CmdletBinding()] 
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FirstName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$LastName, 
    [Parameter(ValueFromPipelineByPropertyName=$true)] 
    [string]$FullName=$null 
) 

Process { 
    if(-not $FullName) { 
     $FullName = "$FirstName $LastName" 
    } 

    $user = "" | select FirstName,LastName,FullName 
    $user.FirstName = $FirstName 
    $user.LastName = $LastName 
    $user.FullName = $FullName 
    return $user 
}