วิธีการเรียกใช้สคริปต์ PowerShell จากแบตช์ไฟล์


197

ฉันพยายามเรียกใช้สคริปต์นี้ใน PowerShell ฉันได้บันทึกสคริปต์ด้านล่างเช่นเดียวps.ps1กับบนเดสก์ท็อปของฉัน

$query = "SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"
Register-WMIEvent -Query $query -Action { invoke-item "C:\Program Files\abc.exe"}

ฉันสร้างสคริปต์ชุดเพื่อเรียกใช้สคริปต์ PowerShell นี้

@echo off
Powershell.exe set-executionpolicy remotesigned -File  C:\Users\SE\Desktop\ps.ps1
pause

แต่ฉันได้รับข้อผิดพลาดนี้:

ป้อนคำอธิบายภาพที่นี่

คำตอบ:


267

คุณต้องการ-ExecutionPolicyพารามิเตอร์:

Powershell.exe -executionpolicy remotesigned -File  C:\Users\SE\Desktop\ps.ps1

มิฉะนั้น PowerShell จะพิจารณาอาร์กิวเมนต์ที่บรรทัดเพื่อดำเนินการและในขณะที่Set-ExecutionPolicy เป็น cmdlet จะไม่มี-Fileพารามิเตอร์


2
@joey มันทำงาน thanks..but หลังจากใช้ไฟล์ค้างคาวผมได้รับข้อผิดพลาดนี้ "Waring: คอลัมน์ 'คำสั่ง' ไม่พอดีกับจอแสดงผลและถูกลบออก"
Eka

นั่นเป็นคำเตือนไม่ใช่ข้อผิดพลาด และอีกเรื่องสำหรับคำถามอื่น
Joey

@joey ควรที่จะเขียนคำถามอื่นใน stack.SE สำหรับคำเตือนเล็กน้อยนี้หรือไม่?
Eka

2
@Joey Haha ดังนั้นคุณสามารถแทนที่นโยบายนี้ได้อย่างมีประสิทธิภาพโดยไม่ต้องเป็นผู้ดูแลระบบ นั่นเป็นปัญหาด้านความปลอดภัยหรือไม่?
Kolob Canyon

2
@KolobCanyon: หากคุณอยู่ในตำแหน่งที่คุณสามารถเรียกใช้ PowerShell ได้คุณสามารถทำทุกอย่างได้ด้วยเช่นกัน โปรดทราบว่านโยบายการดำเนินการไม่ได้หมายความว่า PowerShell มีสิทธิ์มากกว่าที่เป็นไปได้ ด้วยวิธีการที่สะดวกสบายในการหลีกเลี่ยงการทำงานโดยไม่ตั้งใจซึ่งคุณอาจไม่ต้องการใช้ คล้ายกับคำสั่ง prefix ในไดเร็กทอรีปัจจุบันที่มี./และมีแฟล็กที่สามารถเรียกทำงานได้บน Unix
Joey

117

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

นี่คือสิ่งที่คุณกำลังมองหา:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\Users\SE\Desktop\ps.ps1'"

และถ้าคุณต้องการเรียกใช้สคริปต์ PowerShell ในฐานะผู้ดูแลระบบให้ใช้สิ่งนี้:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\Users\SE\Desktop\ps.ps1""' -Verb RunAs}"

แทนที่จะเขียนโค้ดพา ธ ทั้งหมดไปยังสคริปต์ PowerShell อย่างหนักฉันแนะนำให้วางแบตช์ไฟล์และไฟล์สคริปต์ PowerShell ในไดเรกทอรีเดียวกันตามที่โพสต์บล็อกของฉันอธิบาย


Invoke-WebRequest ทำงานได้ดีเมื่อฉันพิมพ์บรรทัดคำสั่งในหน้าต่าง cmd แต่คืนค่า 404 เมื่อใดก็ตามที่ฉันเรียกใช้จากภายในไฟล์แบตช์ ฉันพยายามPowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass Invoke-WebRequest https://www.example.com/example.ics -OutFile C:\_my\script.ics' -Verb RunAs}";หรือpowershell -Command "Invoke-WebRequest https://www.example.com/example.ics -OutFile c:\_my\file.ics"หรือใช้ตัวเลือกแฟ้ม: เดียวกันในแฟ้ม .ps1 (New-Object Net.WebClient).DownloadFileหรือ ความคิดใด ๆ
Chris

ลองใช้ -ExecutionPolicy ไม่ จำกัด ฉันคาดเดาว่าตัวเลือกบายพาสไม่ได้ให้สิทธิ์การเข้าถึงเครือข่าย PowerShell
deadlydog

1
@Belun โพสต์บล็อกที่อ้างอิงแสดงวิธีส่งพารามิเตอร์ไปยังสคริปต์
deadlydog

19

หากคุณต้องการเรียกใช้จากไดเรกทอรีปัจจุบันโดยไม่มีเส้นทางแบบเต็มคุณสามารถใช้:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& './ps.ps1'"

16

หากคุณเรียกใช้แบตช์ไฟล์ที่เรียก PowerShell ในฐานะผู้ดูแลระบบคุณควรเรียกใช้งานแบบนี้ดีกว่าช่วยให้คุณประหยัดทุกปัญหา:

powershell.exe -ExecutionPolicy Bypass -Command "Path\xxx.ps1"

มันจะดีกว่าที่จะใช้Bypass...


3

หากคุณต้องการที่จะทำงานไม่กี่สคริปต์คุณสามารถใช้และตั้งค่าใหม่แล้วด้วยSet-executionpolicy -ExecutionPolicy UnrestrictedSet-executionpolicy -ExecutionPolicy Default

โปรดทราบว่าจะมีการตรวจสอบนโยบายการดำเนินการเฉพาะเมื่อคุณเริ่มการเรียกใช้งาน (หรืออาจดูเหมือน) และเพื่อให้คุณสามารถรันงานในพื้นหลังและรีเซ็ตนโยบายการดำเนินการทันที

# Check current setting
Get-ExecutionPolicy

# Disable policy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
# Choose [Y]es

Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 example.com | tee ping__example.com.txt }
Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 google.com  | tee ping__google.com.txt  }

# Can be run immediately
Set-ExecutionPolicy -ExecutionPolicy Default
# [Y]es

2

อีกวิธีที่ง่ายในการเรียกใช้งานสคริปต์ ps จากแบตช์คือการรวมไว้ระหว่าง ECHO และอักขระการเปลี่ยนเส้นทาง (> และ >>) ตัวอย่างเช่น:

@echo off
set WD=%~dp0
ECHO New-Item -Path . -Name "Test.txt" -ItemType "file" -Value "This is a text string." -Force > "%WD%PSHELLFILE.ps1"
ECHO add-content -path "./Test.txt" -value "`r`nThe End" >> "%WD%PSHELLFILE.ps1"
powershell.exe -ExecutionPolicy Bypass -File "%WD%PSHELLFILE.ps1"
del "%WD%PSHELLFILE.ps1"

บรรทัดสุดท้ายลบไฟล์ชั่วคราวที่สร้างขึ้น


1

หากสคริปต์การเข้าสู่ระบบ PowerShell ของคุณทำงานหลังจาก 5 นาที (ตามเดิม) บนเซิร์ฟเวอร์ 2012 จะมีการตั้งค่า GPO บนเซิร์ฟเวอร์ - 'กำหนดค่าสคริปต์การเข้าสู่ระบบล่าช้า' การตั้งค่าเริ่มต้น 'ไม่ได้กำหนดค่า' ซึ่งจะทำให้ล่าช้า 5 นาที ก่อนรันสคริปต์ล็อกอิน


1

ทดสอบตัวอย่างขนาดเล็ก. cmd

<# :
  @echo off
    powershell /nologo /noprofile /command ^
         "&{[ScriptBlock]::Create((cat """%~f0""") -join [Char[]]10).Invoke(@(&{$args}%*))}"
  exit /b
#>
Write-Host Hello, $args[0] -fo Green
#You programm...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.