3

だから、誰かがここで私を助けてくれることを願っています。私は過去に解決策を探してきましたが、以前は常に何かを見つけていました。しかし、これは奇妙すぎるようです。

New-ADUser コマンドレットを効果的に複製する PowerShell 関数があり、そのために複数のパラメーターを受け入れます。この関数のパラメーターのほとんどは、"ValueFromPipelineByPropertyName" パラメーター属性が True に設定されているため、CSV やその他のパイプライン データを関数に入力できます。多くの "if" ステートメントや代入ステートメントを記述する必要はありません。または、少なくともそれがアイデアでした。

これが私の関数の例です(ポイントをよりよく説明するために縮小されています):

[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 の指定された値がないため、その反復内で使用する値をプロセス ステートメントに設定しています。問題は、$FullName 変数が次のループ反復のためにnullまたは未定義の値に「リセット」されるのではなく、設定された値を保持することです。

FullName の "" 値を明示的に定義するように CSV データを変更すると、問題は解決します。しかし、パイプライン データにプロパティが定義されていない場合、それは役に立ちません。

関数全体を再コーディングして別の変数名を使用したり、 $_を使用したりすることを避けようとしています。これは、関数の複雑さを増すために、HR プログラムのデータベースから直接データを取得してパイプできるようにパラメーター エイリアスも定義しているためです。データを手動でマッサージする必要なく、新しいユーザー関数に追加できます。また、パイプライン データに null 値のパラメーターを追加することはできません。

説明が少し長かったことは承知していますが、シナリオは独特のようです (少なくとも、インターウェブで掘り下げることができるものによると)。

4

3 に答える 3

1

ここで可変スコープで何かトリッキーなことが起こっているのではないでしょうか。

関数の最後にを追加してみてRemove-Variable FullName、それが役立つかどうかを確認できます。

別の変数名を使用したくないことは理解していますが、別の変数を使用して「生成された」フルネームを関数内に格納する方が明確になる場合があります。スコープは、うまくいけば、それほど厄介ではなくなります。

if(-not $FullName) {
    $GeneratedName = "$FirstName $LastName"
} else {
    $GeneratedName = $FullName
}
于 2012-11-09T19:48:02.593 に答える
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
}
于 2012-11-09T20:34:21.840 に答える
0

FullName のデフォルト値を設定する必要があるため、以下のコードは正常に機能します。

[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
}
于 2012-11-10T13:22:25.147 に答える