በበርካታ የ MS-SQL አገልጋዮች ላይ ምትኬን ለማስተዳደር የራሴን ዘዴ ስፈጥር በርቀት ጥሪዎች ወቅት በPowershell ውስጥ እሴቶችን የማለፍ ዘዴን በማጥናት ብዙ ጊዜ አሳልፌያለሁ፣ ስለዚህ ጠቃሚ ከሆነ ለራሴ ማስታወሻ እየጻፍኩ ነው። ለሌላ ሰው።
ስለዚህ፣ በቀላል ስክሪፕት እንጀምርና በአካባቢው እናስኬደው፡-
$exitcode = $args[0]
Write-Host 'Out to host.'
Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)
ስክሪፕቶችን ለማሄድ የሚከተለውን የCMD ፋይል እጠቀማለሁ፣ በእያንዳንዱ ጊዜ አላካተትኩትም።
@Echo OFF
PowerShell .TestOutput1.ps1 1
ECHO ERRORLEVEL=%ERRORLEVEL%
በስክሪኑ ላይ የሚከተለውን እንመለከታለን።
Out to host.
Out to output.
ExitCode: 1
1
ERRORLEVEL=1
አሁን ተመሳሳዩን ስክሪፕት በ WSMAN (በርቀት) እናሂድ፡-
Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
ውጤቱም እነሆ፡-
Out to host.
Out to output.
ExitCode: 2
2
ERRORLEVEL=0
በጣም ጥሩ፣ Errorlevel የሆነ ቦታ ጠፋ፣ ግን እሴቱን ከስክሪፕቱ ማግኘት አለብን! የሚከተለውን ንድፍ እንሞክር.
$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
ይህ ደግሞ የበለጠ ትኩረት የሚስብ ነው። በውጤት ውስጥ ያለው መልእክት የሆነ ቦታ ጠፋ፡-
Out to host.
ExitCode: 2
ERRORLEVEL=0
አሁን፣ እንደ ግጥማዊ ገለጻ፣ በPowershell ተግባር ውስጥ ከፃፍክ Write-Output ወይም ለማንኛውም ተለዋዋጭ ሳትሰጥ አገላለጽ ብቻ (ይህም በውጤት ቻናል ላይ በተዘዋዋሪ የሚያመለክት) መሆኑን አስተውያለሁ። በስክሪኑ ላይ ምንም ነገር አይታይም! ይህ የኃይል ሼል ቧንቧው ሥነ ሕንፃ ውጤት ነው - እያንዳንዱ ተግባር የራሱ የውጤት ቧንቧ መስመር አለው ፣ ለእሱ ድርድር ተፈጠረ ፣ እና ወደ እሱ የሚገባው ነገር ሁሉ የተግባር አፈፃፀም ውጤት እንደሆነ ይቆጠራል ፣ የመመለሻ ኦፕሬተሩ የመመለሻ እሴትን ወደ ተመሳሳይ ይጨምራል። የቧንቧ መስመር እንደ የመጨረሻው አካል እና ቁጥጥርን ወደ ጥሪ ተግባር ያስተላልፋል. ለማብራራት፣ የሚከተለውን ስክሪፕት በአገር ውስጥ እናካሂድ፡-
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: "+$_) }
ውጤቱም እነሆ፡-
Main: ParameterValue
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
2
Main: Function: ParameterValue
Main: ReturnValue
ዋናው ተግባር (ስክሪፕት አካል) የራሱ የውጤት ቧንቧ መስመር አለው፣ እና የመጀመሪያውን ስክሪፕት ከሲኤምዲ ብንሰራ ውጤቱን ወደ ፋይል በማዞር፣
PowerShell .TestOutput1.ps1 1 > TestOutput1.txt
ከዚያም በስክሪኑ ላይ እናያለን
ERRORLEVEL=1
እና በፋይሉ ውስጥ
Out to host.
Out to output.
ExitCode: 1
1
ከኃይል ሼል ተመሳሳይ ጥሪ ካደረግን
PS D:sqlagent> .TestOutput1.ps1 1 > TestOutput1.txt
ከዚያም በማያ ገጹ ላይ ይሆናል
Out to host.
ExitCode: 1
እና በፋይሉ ውስጥ
Out to output.
1
ይህ የሆነበት ምክንያት CMD ሌላ መመሪያ በሌለበት ጊዜ ሁለት ክሮች (አስተናጋጅ እና ውፅዓት) በማደባለቅ እና የተቀበለውን ሁሉ ወደ ፋይል ለሚልክ እና ለሲኤምዲ የሚሰጠውን የኃይል ሼል ስለጀመረ እና ከኃይል ሼል በሚነሳበት ጊዜ። እነዚህ ሁለት ክሮች ለየብቻ አሉ፣ እና ምልክቱ አቅጣጫውን የሚያዞረው በውጤት ላይ ብቻ ነው።
ወደ ዋናው ርዕስ ስንመለስ በኃይል ሼል ውስጥ ያለው የ NET የነገር ሞዴል ሙሉ በሙሉ በአንድ ኮምፒዩተር (አንድ ኦኤስ) ውስጥ እንዳለ እናስታውስ በ WSMAN በርቀት ኮድ ሲሰራ የነገሮችን ማስተላለፍ የሚከናወነው በኤክስኤምኤል ተከታታይነት ሲሆን ይህም ብዙ ተጨማሪ ፍላጎትን ያመጣል። ወደ ምርምራችን። የሚከተለውን ኮድ በማስኬድ ሙከራችንን እንቀጥል፡-
$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$res.GetType()
$host.SetShouldExit($res)
እና እኛ በስክሪኑ ላይ ያለው ይህ ነው-
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
ታላቅ ውጤት! ይህ ማለት ኢንቮክ-ትእዛዝን በሚጠራበት ጊዜ የቧንቧ መስመሮች በሁለት ክሮች (አስተናጋጅ እና ውፅዓት) መከፋፈል ተጠብቆ ይቆያል, ይህም ለስኬት ተስፋ ይሰጠናል. በውጤት ዥረቱ ውስጥ አንድ እሴት ብቻ ለመተው እንሞክር፣ ለዚህም በርቀት የምንሰራውን የመጀመሪያውን ስክሪፕት እንለውጣለን።
$exitcode = $args[0]
Write-Host 'Out to host.'
#Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)
እንዲህ እናስኬደው፡-
$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$host.SetShouldExit($res)
እና... አዎ፣ ድል ይመስላል!
Out to host.
ExitCode: 4
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Int32 System.ValueType
ERRORLEVEL=4
ምን እንደተፈጠረ ለማወቅ እንሞክር. በሃገር ውስጥ ሃይል ሼልን ደወልን፤ እሱም በተራው በራቀት ኮምፒዩተር ላይ ሃይል ሼልን ጠራን እና ስክሪፕታችንን እዛ ላይ ሰራን። ከርቀት ማሽኑ ሁለት ዥረቶች (አስተናጋጅ እና ውፅዓት) በተከታታይ ተደርገዋል እና ወደ ኋላ ተላልፈዋል ፣ የውጤት ዥረቱ በውስጡ አንድ ነጠላ አሃዛዊ እሴት ያለው ፣ ወደ Int32 ዓይነት ተቀይሮ ወደ ተቀባዩ ጎን ተላልፏል እና ተቀባዩ ወገን ተጠቅሞበታል። እንደ ጠሪው የኃይል ሼል መውጫ ኮድ.
እና እንደ የመጨረሻ ፍተሻ፣ በSQL አገልጋይ ላይ “ኦፐሬቲንግ ሲስተም (cmdexec)” አይነት በሚከተለው ጽሁፍ ባለ አንድ ደረጃ ስራ እንፍጠር።
PowerShell -NonInteractive -NoProfile "$res=Invoke-Command -ComputerName BACKUPSERVER -ConfigurationName SQLAgent -ScriptBlock {&'D:sqlagentTestOutput1.ps1' 6}; $host.SetShouldExit($res)"
ሆራይ! ስራው በስህተት ተጠናቅቋል ፣ በምዝግብ ማስታወሻው ውስጥ ጽሑፍ
Выполняется от имени пользователя: DOMAINagentuser. Out to host. ExitCode: 6. Код завершения процесса 6. Шаг завершился с ошибкой.
መደምደሚያ-
- ጻፍ-ውፅዓትን ከመጠቀም እና መግለጫዎችን ያለ ምደባ ከመግለጽ ይቆጠቡ። ይህንን ኮድ በስክሪፕቱ ውስጥ ወደ ሌላ ቦታ ማዛወር ያልተጠበቀ ውጤት ሊያስገኝ እንደሚችል ልብ ይበሉ።
- በእጅ ለማስጀመር የታቀዱ ስክሪፕቶች ላይ ሳይሆን በእራስዎ አውቶማቲክ ስልቶች በተለይም በWINRM በኩል ለርቀት ጥሪዎች በእጅ የስህተት አያያዝን በ Try/Catch በኩል ያድርጉ እና በማንኛውም የክስተቶች እድገት ይህ ስክሪፕት በትክክል አንድ ጥንታዊ እሴት እንደሚልክ ያረጋግጡ። . የሚታወቀውን ስህተት ደረጃ ማግኘት ከፈለጉ፣ ይህ ዋጋ ቁጥራዊ መሆን አለበት።
ምንጭ: hab.com