pscredential plain password parameter credential create powershell invoke-command

parameter - powershell get credential password plain text



¿Cómo paso parámetros nombrados con Invoke-Command? (4)

Tengo un script que puedo ejecutar de forma remota a través de Invoke-Command

Invoke-Command -ComputerName (Get-Content C:/Scripts/Servers.txt) ` -FilePath C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1

Siempre que use parámetros predeterminados, funciona bien. Sin embargo, el script tiene 2 parámetros nombrados [cambiar] (-Debug y -Clear)

¿Cómo puedo pasar los parámetros cambiados a través de Invoke-Command? Probé la -ArgumentList pero recibo errores así que debo tener la sintaxis incorrecta o algo así. Cualquier ayuda es muy apreciada.


Mi solución a esto fue escribir el bloque de scripts dinámicamente con [scriptblock]:Create :

# Or build a complex local script with MARKERS here, and do substitutions # I was sending install scripts to the remote along with MSI packages # ...for things like Backup and AV protection etc. $p1 = "good stuff"; $p2 = "better stuff"; $p3 = "best stuff"; $etc = "!" $script = [scriptblock]::Create("MyScriptOnRemoteServer.ps1 $p1 $p2 $etc") #strings get interpolated/expanded while a direct scriptblock does not # the $parms are now expanded in the script block itself # ...so just call it: $result = invoke-command $computer -script $script

Pasar argumentos fue muy frustrante, probando varios métodos, por ejemplo,
-arguments , $using:p1 , etc. y esto funcionó como se deseó sin problemas.

Como controlo los contenidos y la expansión variable de la cadena que crea el [scriptblock] (o archivo de script) de esta manera, no hay un problema real con el encantamiento "invoke-command".

(No debería ser tan difícil :))


Necesitaba algo para llamar scripts con parámetros nombrados. Tenemos una política de no usar el posicionamiento ordinal de los parámetros y que requiera el nombre del parámetro.

Mi enfoque es similar a los anteriores pero obtiene el contenido del archivo de script que desea llamar y envía un bloque de parámetros que contiene los parámetros y valores.

Una de las ventajas de esto es que, opcionalmente, puede elegir qué parámetros enviar al archivo de secuencia de comandos, lo que permite parámetros no obligatorios con valores predeterminados.

Suponiendo que hay un script llamado "MyScript.ps1" en la ruta temporal que tiene el siguiente bloque de parámetros:

[CmdletBinding(PositionalBinding = $False)] param ( [Parameter(Mandatory = $True)] [String] $MyNamedParameter1, [Parameter(Mandatory = $True)] [String] $MyNamedParameter2, [Parameter(Mandatory = $False)] [String] $MyNamedParameter3 = "some default value" )

Así es como llamaría a este script desde otro script:

$params = @{ MyNamedParameter1 = $SomeValue MyNamedParameter2 = $SomeOtherValue } If ($SomeCondition) { $params[''MyNamedParameter3''] = $YetAnotherValue } $pathToScript = Join-Path -Path $env:Temp -ChildPath MyScript.ps1 $sb = [scriptblock]::create(".{$(Get-Content -Path $pathToScript -Raw)} $(&{ $args } @params)") Invoke-Command -ScriptBlock $sb

Lo he usado en muchos escenarios y funciona muy bien. Una cosa que de vez en cuando debes hacer es poner comillas alrededor del bloque de asignación de valores de parámetros. Este es siempre el caso cuando hay espacios en el valor.

Por ejemplo, este bloque de parámetros se usa para llamar a un script que copia varios módulos en la ubicación estándar utilizada por PowerShell C:/Program Files/WindowsPowerShell/Modules que contiene un carácter de espacio.

$params = @{ SourcePath = "$WorkingDirectory/Modules" DestinationPath = "''$(Join-Path -Path $([System.Environment]::GetFolderPath(''ProgramFiles'')) -ChildPath ''WindowsPowershell/Modules'')''" }

¡Espero que esto ayude!


Sospecho que es una característica nueva desde que se creó esta publicación: pasa los parámetros al bloque de script usando $ Using: var. Entonces, es un simple paso de parámetros siempre que el script ya esté en la máquina o en una ubicación de red conocida con respecto a la máquina

Tomando el ejemplo principal sería:

icm -cn $Env:ComputerName { C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1 -one "uno" -two "dos" -Debug -Clear $Using:Clear }


-ArgumentList se basa en el uso con comandos scriptblock , como:

Invoke-Command -Cn (gc Servers.txt) {param($Debug=$False, $Clear=$False) C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1 } -ArgumentList $False,$True

Cuando lo llamas con un -File aún pasa los parámetros como una matriz splatted tonto. He enviado una solicitud de función para que se agregue al comando (vota eso).

Así que tienes dos opciones:

Si tiene un script que se parece a esto, en una ubicación de red accesible desde el equipo remoto (tenga en cuenta que -Debug está implícito porque cuando uso el atributo Parameter , el script obtiene CmdletBinding implícitamente, y por lo tanto, todos los parámetros comunes):

param( [Parameter(Position=0)] $one , [Parameter(Position=1)] $two , [Parameter()] [Switch]$Clear ) "The test is for ''$one'' and ''$two'' ... and we $(if($DebugPreference -ne ''SilentlyContinue''){"will"}else{"won''t"}) run in debug mode, and we $(if($Clear){"will"}else{"won''t"}) clear the logs after."

Sin obsesionarse con el significado de $Clear ... si desea invocar que puede usar cualquiera de las siguientes sintaxis Invoke-Command :

icm -cn (gc Servers.txt) { param($one,$two,$Debug=$False,$Clear=$False) C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1 @PSBoundParameters } -ArgumentList "uno", "dos", $false, $true

En ese caso, estoy duplicando TODOS los parámetros que me interesan en el scriptblock para poder pasar valores. Si puedo codificarlos (que es lo que realmente hice), no hay necesidad de hacer eso y usar PSBoundParameters , solo puedo pasar los que necesito. En el segundo ejemplo a continuación voy a pasar el $ Borrar uno, solo para demostrar cómo pasar los parámetros del interruptor:

icm -cn $Env:ComputerName { param([bool]$Clear) C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1 "uno" "dos" -Debug -Clear:$Clear } -ArgumentList $(Test-Path $Profile)

La otra opción

Si el script está en su máquina local, y no desea cambiar los parámetros para que sean posicionales, o si desea especificar parámetros que son parámetros comunes (para que no pueda controlarlos), querrá obtener el contenido de ese script e incrústelo en su scriptblock :

$script = [scriptblock]::create( @" param(`$one,`$two,`$Debug=`$False,`$Clear=`$False) &{ $(Get-Content C:/Scripts/ArchiveEventLogs/ver5/ArchiveEventLogs.ps1 -delimiter ([char]0)) } @PSBoundParameters "@ ) Invoke-Command -Script $script -Args "uno", "dos", $false, $true

Posdata:

Si realmente necesita pasar una variable para el nombre del script, lo que haría dependerá de si la variable se define de forma local o remota. En general, si tiene un $Script variable o una variable de entorno $Env:Script con el nombre de un script, puede ejecutarlo con el operador de llamada (&): &$Script o &$Env:Script

Si se trata de una variable de entorno que ya está definida en la computadora remota, eso es todo. Si se trata de una variable local , deberá pasarla al bloque de script remoto:

Invoke-Command -cn $Env:ComputerName { param([String]$Script, [bool]$Clear) &$Script "uno" "dos" -Debug -Clear:$Clear } -ArgumentList $ScriptPath, $(Test-Path $Profile)