การอ้างอิงบริบทของเอเจนต์ SQL PowerShell


13

ที่งานใหม่ของฉันเรามีอินสแตนซ์ที่มีชื่อหลายรายการในแต่ละเซิร์ฟเวอร์ เช่น

  • Server1 \ Dev
  • Server1 \ DevIntegrated
  • Server1 \ QA

ฉันมีสคริปต์ SQL PowerShell ในงานที่เรียกไปยังระบบปฏิบัติการเรียกใช้Foo.exeแต่ต้องผ่านพารามิเตอร์บรรทัดคำสั่ง (สตริงการเชื่อมต่อ) งาน SQL Agent จะมีอยู่ในแต่ละอินสแตนซ์ด้วยขั้นตอนการพิมพ์ PowerShell ที่จำเป็นต้องรู้ว่าบริบทปัจจุบันคืออะไร ieการดำเนินการนี้เริ่มต้นบน DevIntegrated

ฉันไม่ต้องการให้สคริปต์เริ่มต้นด้วย ...

$thisInstance = "Dev"

... โดยเฉพาะอย่างยิ่งเมื่อฉันต้องแก้ไขว่าเมื่อเราย้ายไปยังสภาพแวดล้อม (เซิร์ฟเวอร์ใหม่และอินสแตนซ์ที่มีชื่อ) ในอีกไม่กี่เดือนข้างหน้า

ถ้าฉันเริ่ม SQLPS ฉันสามารถกำหนดอินสแตนซ์ของฉันโดยการแบ่งส่วนและทำให้ผลลัพธ์ของ Get-Location หรือทำงาน

(Invoke-Sqlcmd -Query "SELECT @@servername AS ServerName" -SuppressProviderContextWarning).ServerName

เมื่อตัวแทนของ SQL เริ่มงานประเภท PowerShell จะเริ่มใน C: \ windows \ system32 และGet-Locationเส้นทางไม่ทำงานเนื่องจากไม่ได้อยู่ในบริบทของ SQLSERVER ฉันสามารถเปลี่ยนเป็นบริบทนั้นได้ แต่ฉันจะอยู่ที่ "รูท" ของ SQL Server และไม่ทราบว่าควรใช้อินสแตนซ์ใดการใช้Invoke-Sqlcmdเส้นทางจะไม่ทำงานด้วยเหตุผลเดียวกัน (ในทางเทคนิค ไม่มีอินสแตนซ์เริ่มต้น)

เพื่อความรู้ที่ดีที่สุดของฉันฉันได้ระบุ "สิ่ง" พื้นฐานทั้งหมดที่ฉันสามารถเข้าไปในบันทึกการใช้งาน แต่ดูเหมือนจะไม่มีอะไรแสดง SQLSERVER:\SQL\Server1\DevIntegrated

Get-Processดูเหมือนว่าฉันจะสามารถใช้มันและวูดูพยายามทำสิ่งต่าง ๆ ด้วยกันโดยการกดอินสแตนซ์และสปินที่เข้าคู่กัน แต่ดูเหมือนว่าจะเป็นการแฮ็คเลือดจากนรก จะต้องมีบางสิ่งพื้นฐานที่ฉันขาดหายไปใครจะมีความสว่างได้บ้าง?

ทางเลือกในการตรวจสอบ PowerShell

ฉันตรวจสอบโดยใช้งานประเภทอื่นและไม่ได้รับการแก้ไขที่น่าพอใจ การวิจัยระบุว่า PowerShell ที่แสดงรายการภายใต้ SQL Agent คือ SQLPS และเริ่มต้นอินสแตนซ์ของมันโดยการคลิกขวาที่ Agent โดยอัตโนมัติทำให้ฉันตกอยู่ในตำแหน่งที่ถูกต้องโดยอัตโนมัติ มันก็ต่อเมื่อฉันวางโค้ดเชิงโต้ตอบลงในขั้นตอนงานที่ฉันได้เรียนรู้ถึงความแตกต่างดังที่ได้กล่าวไว้ก่อนหน้านี้

ประเภทงานของระบบปฏิบัติการทำให้ฉันอยู่ในสถานะที่เหมือนกันซึ่งฉันไม่สามารถหาวิธีที่จะกำหนดอินสแตนซ์ที่ทำให้ฉันลงในเชลล์คำสั่ง แน่นอนว่าฉันสามารถ sqlcmd และรับค่าของ@@servernameแต่ถ้าฉันรู้ว่าการเชื่อมต่อเพื่อเริ่ม sqlcmd ฉันไม่จำเป็นต้องค้นหาฐานข้อมูล;)

TSQL อาจทำงานได้ถ้าเราเปิดใช้งานxp_cmdshellแต่ฉันไม่แน่ใจว่าพวกเขาเปิดใช้งานแล้วหรือไม่ --- สิ่งอำนวยความสะดวกของรัฐบาลและพวกเขาสามารถตั้งค่าที่ไม่ใช่ค่าเริ่มต้นได้ ถึงอย่างนั้นฉันก็ติดการเปลี่ยนแปลงกับ SQL แบบไดนามิกและสูญเสียความหมายและพลังที่ PowerShell ให้ยืมมากมาย

ในขณะที่ค่อนข้างไม่สุภาพฉันคิดว่าการกำหนดตัวแปรในขั้นตอนแรกและส่งต่อไปยังขั้นตอนการสืบทอด แต่การวิจัยเปิดบทความนี้การจัดการหลายขั้นตอนงาน (BOL)

ขั้นตอนของงานต้องอยู่ในตัวเอง นั่นคืองานไม่สามารถส่งผ่านค่าบูลีนข้อมูลหรือค่าตัวเลขระหว่างขั้นตอนงาน อย่างไรก็ตามคุณสามารถส่งค่าจากขั้นตอนงาน Transact-SQL หนึ่งไปยังอีกขั้นได้โดยใช้ตารางถาวรหรือตารางชั่วคราวทั่วโลก คุณสามารถส่งผ่านค่าจากขั้นตอนงานที่รันโปรแกรมปฏิบัติการจากขั้นตอนงานหนึ่งไปยังขั้นตอนงานอื่นโดยใช้ไฟล์

ฉันไม่สามารถใช้ลูกเล่นทั่วไปเช่นการตั้งค่าไฟล์ / สภาพแวดล้อมตัวแปร / การตั้งค่ารีจิสทรีที่Foo.exeเป็นที่รู้จักเนื่องจากจะป้องกันการทำงานพร้อมกันข้ามอินสแตนซ์

TL; DR:

ในขั้นตอนงานตัวแทน SQL ประเภท PowerShell คุณจะกำหนดอินสแตนซ์ของ SQL Server ที่เปิดใช้งานกระบวนการได้อย่างไร


4
PowerShell เป็นข้อกำหนดสำหรับสิ่งที่คุณทำหรือไม่?
johndacostaa

ความต้องการที่แท้จริงคือการมี "บางสิ่ง" ใน reuasble ในเอเจนต์ SQL ที่สามารถเปิดใช้งานกระบวนการ DOS ด้วยพารามิเตอร์ของอินสแตนซ์ที่เรียกใช้ PowerShell ดูเหมือนว่าเหมาะสมที่สุดสำหรับสิ่งที่ไม่ได้ทำงานด้านบน ขอโทษที่ตอบช้าฉันออกไปที่ค่ายลูกเสือ
billinkc

คำตอบ:


9

หากคุณดูใน SQL Server BOL ตัวแทนของเซิร์ฟเวอร์ SQL จะมีชุด "โทเค็น" ซึ่งจะแทนที่ทั้งข้อความคำสั่งขั้นตอนงานและไฟล์เอาต์พุต (ภายหลังจะป้องกันปุ่ม GUI "มุมมอง" จากการทำงาน) โทเค็นเหล่านี้ดูเหมือนจะใช้ได้กับทุกขั้นตอนยกเว้น T-SQL

https://docs.microsoft.com/en-us/sql/ssms/agent/use-tokens-in-job-steps#sql-server-agent-tokens

ดังนั้นหากคุณมีขั้นตอน SQL 2008 PowerShell คุณสามารถเริ่มต้นด้วย:

$sqlInstance = "$(ESCAPE_DQUOTE(SRVR))"

คุณอาจจะต้องใช้MACH(ชื่อเครื่อง) และINST(เพียงแค่ชื่ออินสแตนซ์) แทนเพราะมีอินสแตนซ์เริ่มต้นแต่มีกรณีการตั้งชื่อSRVR == MACHSRVR == MACH\INST


3

น่าเสียดายที่ฉันไม่ได้ทำอะไรมากมายกับสคริปต์ PowerShell ที่ถูกเรียกใช้ใน SQL Server ฉันไม่ได้ใช้คอมพิวเตอร์ที่ฉันสามารถเล่นกับมันได้ในตอนนี้

ฉันเชื่อว่าแทนที่จะใช้ขั้นตอน PowerShell พิมพ์ว่าถ้าคุณใช้ CmdExec และเพียงเรียกสคริปต์ของคุณตามที่คุณต้องการจากบรรทัดคำสั่ง "powershell 'MyScript.ps1'" คุณสามารถส่งพารามิเตอร์ที่มีอินสแตนซ์ที่คุณใช้งานอยู่ เช่น "Powershell 'MyScript.ps1' MyInstanceName"

ดังนั้นการเริ่มต้นของสคริปต์ของคุณคุณมีการตั้งค่าพารามิเตอร์ () เพื่อยอมรับค่าของ MyInstanceName:


param(
   [Parameter(Position=0,Mandatory=$True)]
   [string]$InstanceName
)
#so if I wanted to use sqlcmd
sqlcmd -S $InstanceName -Q "SELECT @@VERSION"

ในขณะที่คุณเริ่มต้นระบุขั้นตอนเดียวที่จำเป็นต้องทราบว่าอินสแตนซ์ใดอยู่เพื่อให้สคริปต์ PowerShell สามารถเรียก Foo.exe ได้อย่างถูกต้อง อย่างไรก็ตามในภายหลังคุณพูดถึงความสามารถในการส่งผ่านค่าไปยังขั้นตอนอื่น ๆ หากเป็นจริงคุณอาจต้องการสร้างแพ็คเกจ SSIS ขนาดเล็กที่เรียกสคริปต์ PowerShell ของคุณและทำสิ่งอื่นที่คุณต้องการ ด้วย SSIS คุณสามารถตั้งค่าตัวแปรส่วนกลางที่ทั้งแพ็คเกจสามารถใช้ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.