มีวิธีที่จะระงับการแจ้งให้โต้ตอบในสคริปต์ PowerShell หรือไม่


13

เมื่อเขียนสคริปต์ PowerShell ฉันสังเกตว่าเมื่อ cmdlets บางตัวประสบปัญหาพวกเขาแสดงพรอมต์แบบโต้ตอบ Remove-Item ในไดเรกทอรีที่ไม่ว่างเปล่าเป็นตัวอย่าง นี่เป็นเรื่องร้ายแรงเมื่อพยายามทำให้งานเป็นไปโดยอัตโนมัติฉันต้องการทำสิ่งที่ล้มเหลวและทิ้งข้อยกเว้นหรือส่งคืนรหัสส่งคืนที่ไม่ดีเพื่อให้สคริปต์ทั้งหมดไม่ถูกล็อครอการตอบกลับ

มีวิธีใดที่จะบังคับให้ PowerShell ล้มเหลวโดยอัตโนมัติซึ่งต่างจากการค้นหาอินพุตของผู้ใช้ในการทำงานหรือไม่


ฉันคิดว่าคุณควรเปลี่ยนชื่อคำถามของคุณ "ฉันจะทำให้Remove-Itemล้มเหลวอย่างรวดเร็วได้อย่างไร"
Jay Bazuzi

1
นี่ไม่ได้เกี่ยวกับการลบรายการโดยเฉพาะ แต่เป็นเพียงตัวอย่างเท่านั้น มี cmdlet อื่น ๆ อีกมากมายที่จะบล็อกการรออินพุตของผู้ใช้ภายใต้เงื่อนไขที่ถูกต้อง
Chuu

คำตอบ:


5

โซลูชันที่เสนอโดย Eris เริ่มต้นอินสแตนซ์ PowerShell อื่นอย่างมีประสิทธิภาพ อีกทางเลือกหนึ่งในการทำเช่นนี้โดยมีไวยากรณ์ที่ง่ายกว่าคือการใช้เชลล์กับอินสแตนซ์อื่นของ powershell.exe

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"

2
ฉันชอบวิธีการแก้ปัญหา แต่มันนำกลับมาฝันร้ายของการเขียนขั้นตอนการจัดเก็บที่เชื่อถือได้ใน TSQL ก่อนที่จะลอง / จับซึ่งต้องรอบตัวอักษรทุกแบบสอบถามที่มีการตรวจสอบข้อผิดพลาดสำเร็จรูป
Chuu

4

ดูGet-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    กำหนดว่า Windows PowerShell จะแจ้งให้คุณทราบโดยอัตโนมัติหรือไม่
    ยืนยันก่อนที่จะใช้ cmdlet หรือฟังก์ชั่น

...

ไม่มี: Windows PowerShell ไม่ได้แจ้งโดยอัตโนมัติ
                         หากต้องการขอการยืนยันคำสั่งเฉพาะให้ใช้
                         พารามิเตอร์ยืนยันของ cmdlet หรือฟังก์ชัน

ดังนั้น:

> $ConfirmPreference = 'None'

ฉันพบว่าการดูปัญหาฉันต้องตั้งค่า $ ConfirmPreference = 'ต่ำ'
Guy Thomas

สิ่งนี้ไม่ทำงาน ลบรายการในไดเรกทอรียังให้คุณพร้อมท์หลังจากตั้งค่า $ ConfirmPreference เป็น 'ไม่มี' หรือ 'ต่ำ'
Chuu

ผลงานRemove-ADUser(เซิร์ฟเวอร์ 2012R)
velkoon

2

โอเคนี่มันช่างน่าเกลียดจริงๆ แต่มัสตาร์ดศักดิ์สิทธิ์เปื้อนมัน "งาน"

ปัญหาที่พบ:

  • ฉันไม่ได้คิดวิธีการดำเนินการต่อหลังจากข้อผิดพลาดแรก
  • ในกรณีนี้มันจะลบไฟล์ธรรมดาจากนั้นหยุดที่โฟลเดอร์แรก
  • ฉันยังไม่ได้คิดวิธีที่จะทำให้ cmdlet นี้ทำงานถ้าฉันเพิ่มพารามิเตอร์ UseTransaction
  • สิ่งนี้จะใช้ได้กับกรณีแบบง่าย (คำสั่งที่ไม่ได้ทำอะไรมากมายกับสภาพแวดล้อมปัจจุบัน) ฉันยังไม่ได้ทดสอบอะไรที่ซับซ้อน

    $MyPS = [Powershell]::Create()
    $MyPS.Commands.AddCommand("Remove-Item")
    $MyPS.Commands.AddParameter("Path", "D:\Temp\t")
    $MyPS.Invoke()

เอาท์พุท:

Commands                                                                                                                 
--------                                                                                                                 
{Remove-Item}                                                                                                            
{Remove-Item}                                                                                                            
Exception calling "Invoke" with "0" argument(s): "A command that prompts the user failed because the host program or the 
command type does not support user interaction. The host was attempting to request confirmation with the following 
message: The item at D:\Temp\t has children and the Recurse parameter was not specified. If you continue, all children 
will be removed with the item. Are you sure you want to continue?"
At line:19 char:1
+ $MyPS.Invoke()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CmdletInvocationException

เหตุผลที่ฉันไม่ได้ทำเครื่องหมายว่านี่เป็นวิธีแก้ปัญหาคือฉันไม่ได้มีเวลาในการทดสอบ มีใครปรับใช้หรือทดสอบรหัสนี้นอกเหนือจากผู้เขียน?
Chuu

0

โซลูชันด้านบนทั้งหมดล้มเหลวสำหรับฉันเมื่อฉันสร้างไดเรกทอรีซึ่งหมายความว่าฉันได้รับแจ้งให้ตกลงทุกไดเรกทอรีเดียวที่สคริปต์ของฉันสร้างขึ้น - ซึ่งมีมาก สิ่งที่ใช้ได้ผลสำหรับฉันคือการตรวจสอบ | Out-null เพื่อไพพ์ผลลัพธ์ไปยัง Out-Null

New-Item -ItemType Directory -Path $directory -Force:$true | Out-Null

โปรดทราบว่า $ Directory เป็นสตริงที่มีเส้นทางแบบเต็มไปยังไดเรกทอรีที่คุณต้องการสร้าง หวังว่านี่จะช่วยให้ใครซักคนได้เวลา: หน้า


-1

ฉันแนะนำสองเทคนิค

a) ผนวก -force

b) ผนวก -errorAction silently continue

นี่คือวิธีที่ฉันวิจัยว่า cmdlets สนับสนุนพารามิเตอร์เฉพาะ

Get-Command | where { $_.parameters.keys -contains "erroraction"}

หนึ่งในเหตุผลที่ฉันเริ่มต้นเส้นทางนี้คือฉันมักจะต้องการที่จะทำในสิ่งที่ตรงกันข้ามกับ -force นั่นคือ -alwaysbackoff ฉันพบว่าคำสั่งส่วนใหญ่ที่สนับสนุน -force ดูเหมือนจะไม่มีตัวเลือกใด ๆ ที่จะถอยกลับแม้ว่า
Chuu

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