Famerenana sanda avy amin'ny baiko-invoke powershell mankany amin'ny mpandraharaha SQL Server

Rehefa namorona ny fomba fiasako manokana amin'ny fitantanana backup amin'ny server MS-SQL maro aho, dia nandany fotoana be tamin'ny fianarana ny mekanika handefasana soatoavina ao amin'ny Powershell mandritra ny antso lavitra, ka manoratra fampahatsiahivana ho ahy aho raha toa ka mahasoa izany. amin’olon-kafa.

Noho izany, andeha isika hanomboka amin'ny script tsotra ary hampandeha azy eo an-toerana:

$exitcode = $args[0]
Write-Host 'Out to host.'
Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)

Mba hampandehanana script dia hampiasa ity rakitra CMD manaraka ity aho, tsy hampiditra azy io isaky ny misy aho:

@Echo OFF
PowerShell .TestOutput1.ps1 1
ECHO ERRORLEVEL=%ERRORLEVEL%

Eo amin'ny efijery dia hahita ireto manaraka ireto isika:

Out to host.
Out to output.
ExitCode: 1
1
ERRORLEVEL=1


Andeha isika hanao an'io script io amin'ny alàlan'ny WSMAN (lavitra):

Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]

Ary izao no vokany:

Out to host.
Out to output.
ExitCode: 2
2
ERRORLEVEL=0

Tsara, Errorlevel nanjavona tany ho any, fa mila maka ny sanda avy amin'ny script! Andeha isika hanandrana ity fanorenana manaraka ity:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]

Mbola mahaliana kokoa izany. Nanjavona tany ho any ny hafatra ao amin'ny Output:

Out to host.
ExitCode: 2
ERRORLEVEL=0

Ankehitriny, ho toy ny digression lyrical, ho marihiko fa raha ao anatin'ny Powershell miasa ianao manoratra Write-Output na fanehoana fotsiny nefa tsy manendry azy amin'ny fari-piainana (ary izany dia midika hoe vokatra amin'ny fantsona Output), dia na dia mihazakazaka eo an-toerana aza, tsy hisy haseho eo amin'ny efijery! Izany dia vokatry ny rafitra pipeline powershell - ny asa tsirairay dia manana ny Output pipeline manokana, misy array iray noforonina ho azy, ary izay rehetra miditra ao dia heverina ho vokatry ny fanatanterahana ny asa, ny Return operator dia manampy ny sandan'ny fiverenana mitovy. pipeline ho singa farany ary mamindra ny fanaraha-maso amin'ny asa fiantsoana. Mba hanazavana dia andao hatao eto an-toerana ity script manaraka ity:

Function Write-Log {
  Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [String[]] $OutString = "`r`n" )
  Write-Output ("Function: "+$OutString)
  Return "ReturnValue"
}
Write-Output ("Main: "+"ParameterValue")
$res = Write-Log "ParameterValue"
$res.GetType()
$res.Length
$res | Foreach-Object { Write-Host ("Main: "+$_) }

Ary izao no vokany:

Main: ParameterValue

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
2
Main: Function: ParameterValue
Main: ReturnValue

Ny asa lehibe (vatan'ny script) dia manana ny fantsona Output azy manokana, ary raha mihazakazaka ny script voalohany avy amin'ny CMD isika, mamindra ny vokatra amin'ny rakitra iray,

PowerShell .TestOutput1.ps1 1 > TestOutput1.txt

dia ho hitantsika eo amin'ny efijery

ERRORLEVEL=1

ary ao anaty rakitra

Out to host.
Out to output.
ExitCode: 1
1

raha manao antso mitovy amin'izany avy amin'ny powershell isika

PS D:sqlagent> .TestOutput1.ps1 1 > TestOutput1.txt

dia ho eo amin'ny efijery izany

Out to host.
ExitCode: 1

ary ao anaty rakitra

Out to output.
1

Mitranga izany satria ny CMD dia mandefa powershell, izay, raha tsy misy torolalana hafa, dia mampifangaro kofehy roa (Host sy Output) ary manome azy ireo amin'ny CMD, izay mandefa ny zavatra rehetra azony amin'ny rakitra iray, ary raha ny fandefasana avy amin'ny powershell, Misy misaraka ireo kofehy roa ireo, ary ny famerenan'ny marika dia misy fiantraikany amin'ny Output ihany.

Miverina amin'ny lohahevitra fototra, aoka ho tsaroantsika fa ny modely .NET object ao anaty powershell dia misy tanteraka ao anatin'ny solosaina iray (OS iray), rehefa mihazakazaka kaody lavitra amin'ny alàlan'ny WSMAN, ny famindrana zavatra dia mitranga amin'ny alàlan'ny serialization XML, izay mitondra tombontsoa fanampiny be dia be. amin'ny fikarohanay. Andao hanohy ny andrana ataontsika amin'ny fampandehanana ity kaody manaraka ity:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$res.GetType()
$host.SetShouldExit($res)

Ary izao no ananantsika eo amin'ny efijery:

Out to host.

ExitCode: 3

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
Не удается преобразовать аргумент "exitCode", со значением: "System.Object[]", для "SetShouldExit" в тип "System.Int32": "Не удается преобразовать значение "System.Object[]" типа "System.Object[]" в тип "System
.Int32"."
D:sqlagentTestOutput3.ps1:3 знак:1
+ $host.SetShouldExit($res)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

ERRORLEVEL=0

Vokatra tsara! Midika izany fa rehefa miantso Invoke-Command dia tazonina ny fizarana ny fantsona ho kofehy roa (Host sy Output), izay manome fanantenana ho an'ny fahombiazana. Andeha isika hiezaka hamela sanda iray ihany ao amin'ny Output stream, izay hanovantsika ny script voalohany izay mandeha lavitra:

$exitcode = $args[0]
Write-Host 'Out to host.'
#Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)

Andao hatao toy izao:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$host.SetShouldExit($res)

ary... ENY, toa fandresena!

Out to host.
ExitCode: 4

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType


ERRORLEVEL=4

Andeha hojerentsika izay nitranga. Nantsoinay teo an-toerana ny powershell, izay nantsoina indray hoe powershell tamin'ny solosaina lavitra ary nanatanteraka ny scripty tao. Ny renirano roa (Host sy Output) avy amin'ny milina lavitra dia nozaraina ary naverina, raha ny Output stream, izay manana sanda nomerika tokana ao anatiny, dia navadika ho karazana Int32 ary toy izany no nifindra tany amin'ny lafiny fandraisana, ary ny lafiny mpandray dia nampiasa azy io. toy ny kaody fivoahana amin'ny powershell mpiantso.

Ary ho fanamarinana farany, andao hamorona asa dingana iray amin'ny mpizara SQL miaraka amin'ny karazana "Rafitra fandidiana (cmdexec)" miaraka amin'ireto lahatsoratra manaraka ireto:

PowerShell -NonInteractive -NoProfile "$res=Invoke-Command -ComputerName BACKUPSERVER -ConfigurationName SQLAgent -ScriptBlock {&'D:sqlagentTestOutput1.ps1' 6}; $host.SetShouldExit($res)"

HOORAY! Ny asa vita tamin'ny fahadisoana, lahatsoratra ao amin'ny log:

Выполняется от имени пользователя: DOMAINagentuser. Out to host. ExitCode: 6.  Код завершения процесса 6.  Шаг завершился с ошибкой.

fehin-kevitra:

  • Ialao ny fampiasana Write-Output ary manonona teny tsy misy fanendrena. Tandremo fa mety hiteraka vokatra tsy ampoizina ny famindrana ity kaody ity any an-kafa ao amin'ny script.
  • Ao amin'ny script tsy natao ho an'ny fandefasana manual, fa ampiasaina amin'ny mekanika automatique anao, indrindra ho an'ny antso lavitra amin'ny alàlan'ny WINRM, ataovy ny fitantanana ny fahadisoana amin'ny alàlan'ny Try/Catch, ary ho azo antoka fa, amin'ny fivoaran'ny hetsika rehetra, ity script ity dia mandefa sanda karazana primitive iray. . Raha te-hahazo ny Errorlevel mahazatra ianao dia tsy maintsy isa io sanda io.

Source: www.habr.com

Add a comment