Mayar da ƙima daga umarnin kira-powershell zuwa wakilin SQL Server

Lokacin ƙirƙirar nawa hanya don sarrafa madadin akan sabar MS-SQL da yawa, na ɗauki lokaci mai yawa don nazarin tsarin wucewar ƙima a cikin Powershell yayin kiran nesa, don haka ina rubuta tunatarwa ga kaina idan yana da amfani. ga wani.

Don haka, bari mu fara da rubutu mai sauƙi kuma mu gudanar da shi a cikin gida:

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

Don gudanar da rubutun, zan yi amfani da fayil ɗin CMD mai zuwa, ba zan haɗa shi ba kowane lokaci:

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

A kan allon za mu ga abubuwa masu zuwa:

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


Yanzu bari mu gudanar da wannan rubutun ta hanyar WSMAN (a nesa):

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

Ga sakamakon:

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

Babban, Errorlevel ya ɓace a wani wuri, amma muna buƙatar samun ƙimar daga rubutun! Bari mu gwada zane mai zuwa:

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

Wannan ma ya fi ban sha'awa. Sakon da ke cikin Fitowa ya ɓace a wani wuri:

Out to host.
ExitCode: 2
ERRORLEVEL=0

Yanzu, a matsayin digression lyrical, Zan lura cewa idan a cikin wani Powershell aikin ka rubuta Rubuta-Output ko kawai magana ba tare da sanya shi zuwa wani m (kuma wannan a fakaice yana nuna fitarwa zuwa tashar fitarwa), to, ko da a cikin gida. babu abin da za a nuna akan allon! Wannan shi ne sakamakon gine-ginen bututun wutar lantarki - kowane aiki yana da nasa bututun fitarwa, an ƙirƙira masa tsararru, kuma duk abin da ya shiga cikinsa ana ɗaukarsa sakamakon aiwatar da aikin, ma'aikacin Return yana ƙara ƙimar dawowa zuwa iri ɗaya. bututu a matsayin kashi na ƙarshe kuma yana canja wurin sarrafawa zuwa aikin kira. Don kwatanta, bari mu gudanar da rubutun nan a cikin gida:

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: "+$_) }

Kuma ga sakamakon:

Main: ParameterValue

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

Babban aikin (jigon rubutun) shima yana da nasa bututun fitarwa, kuma idan muka gudanar da rubutun farko daga CMD, ana tura fitarwa zuwa fayil,

PowerShell .TestOutput1.ps1 1 > TestOutput1.txt

to za mu gani a kan allo

ERRORLEVEL=1

kuma a cikin fayil

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

idan muka yi irin wannan kira daga powershell

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

to zai kasance akan allo

Out to host.
ExitCode: 1

kuma a cikin fayil

Out to output.
1

Wannan yana faruwa ne saboda CMD yana ƙaddamar da powershell, wanda, idan babu wasu umarni, yana haɗa zaren guda biyu (Mai watsa shiri da fitarwa) sannan ya ba su CMD, wanda ke aika duk abin da aka karɓa zuwa fayil, kuma a yanayin ƙaddamarwa daga powershell. waɗannan zaren guda biyu suna wanzu daban, kuma alamar tana jujjuyawar tana shafar fitarwa kawai.

Komawa ga babban batu, bari mu tuna cewa samfurin abu na .NET a cikin powershell ya kasance cikakke a cikin kwamfuta ɗaya (OS guda ɗaya), lokacin da ke gudana code ta hanyar WSMAN, canja wurin abubuwa yana faruwa ta hanyar serialization XML, wanda ke kawo ƙarin ƙarin sha'awa. zuwa ga bincikenmu. Mu ci gaba da gwaje-gwajenmu ta hanyar gudanar da lamba mai zuwa:

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

Kuma wannan shine abin da muke da shi akan allon:

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

Babban sakamako! Yana nufin cewa lokacin da ake kira Invoke-Command, ana kiyaye rarraba bututun zuwa zare guda biyu (Mai watsa shiri da fitarwa), wanda ke ba mu fatan samun nasara. Bari mu yi ƙoƙari mu bar ƙima ɗaya kawai a cikin rafi na fitarwa, wanda za mu canza ainihin rubutun farko wanda muke aiki daga nesa:

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

Bari mu gudanar da shi kamar haka:

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

kuma ... E, yana kama da nasara!

Out to host.
ExitCode: 4

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


ERRORLEVEL=4

Mu yi kokarin gano abin da ya faru. Mun kira powershell a cikin gida, wanda kuma ake kira powershell a kan kwamfutar tafi-da-gidanka kuma muka aiwatar da rubutun mu a can. Rafukan guda biyu (Mai watsa shiri da fitarwa) daga na'ura mai nisa an jera su kuma sun koma baya, yayin da rafi na Output, yana da ƙimar dijital guda ɗaya a ciki, an canza shi zuwa nau'in Int32 kuma don haka ya wuce zuwa ɓangaren karɓa, kuma ɓangaren karɓa ya yi amfani da shi. azaman lambar fita na mai kira powershell.

Kuma a matsayin bincike na ƙarshe, bari mu ƙirƙiri aikin mataki ɗaya akan uwar garken SQL tare da nau'in "Operating System (cmdexec)" tare da rubutu mai zuwa:

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

HAKA! An kammala aikin da kuskure, rubutu a cikin log ɗin:

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

Ƙarshe:

  • Guji yin amfani da Fitar da Rubutu da ƙayyadaddun maganganu ba tare da aiki ba. Ku sani cewa matsar da wannan lambar zuwa wani wuri a cikin rubutun na iya haifar da sakamako mara tsammani.
  • A cikin rubutun da aka yi niyya ba don ƙaddamar da hannu ba, amma don amfani a cikin hanyoyin sarrafa kansa, musamman don kira mai nisa ta hanyar WINRM, yi sarrafa kuskuren hannu ta hanyar Gwada/Catch, kuma tabbatar da cewa, a cikin kowane ci gaban abubuwan da suka faru, wannan rubutun yana aika daidai nau'in ƙima guda ɗaya. . Idan kana son samun daidaitaccen matakin Kuskuren, wannan ƙimar dole ne ta zama lamba.

source: www.habr.com

Add a comment