If-Koubou

Cara Menggunakan File Batch untuk Membuat Script PowerShell Lebih Mudah Dijalankan

Cara Menggunakan File Batch untuk Membuat Script PowerShell Lebih Mudah Dijalankan (Bagaimana caranya)

Untuk beberapa alasan, sebagian besar terkait dengan keamanan, skrip PowerShell tidak mudah dibawa-bawa dan dapat digunakan sebagai skrip batch. Namun, kami dapat menggabungkan skrip batch dengan skrip PowerShell kami untuk mengatasi masalah ini. Di sini, kami akan menunjukkan beberapa area masalah tersebut, dan cara membuat skrip batch untuk mengelilinginya.

Mengapa saya tidak bisa menyalin file .PS1 saya ke komputer lain dan menjalankannya?

Kecuali sistem target telah dikonfigurasi sebelumnya untuk memungkinkan menjalankan skrip acak, dengan hak istimewa yang diperlukan, dan menggunakan pengaturan yang benar, kemungkinan Anda akan mengalami beberapa masalah ketika Anda mencoba melakukan ini.

  1. PowerShell tidak terkait dengan ekstensi file .PS1 secara default.
    Kami mengangkat ini awalnya di seri PowerShell Geek School kami. Asosiasi Windows. File PS1 ke Notepad secara default, daripada mengirimnya ke interpreter perintah PowerShell. Ini untuk mencegah eksekusi skrip berbahaya secara tidak sengaja hanya dengan mengklik dua kali. Ada beberapa cara Anda dapat mengubah perilaku ini, tetapi itu mungkin bukan sesuatu yang ingin Anda lakukan di setiap komputer yang Anda bawa skrip Anda ke - terutama jika beberapa komputer itu bukan milik Anda sendiri.
  2. PowerShell tidak mengizinkan eksekusi skrip eksternal secara default.
    Pengaturan ExecutionPolicy di PowerShell mencegah eksekusi skrip eksternal secara default di semua versi Windows. Di beberapa versi Windows, standarnya tidak memungkinkan eksekusi skrip sama sekali. Kami menunjukkan kepada Anda cara mengubah pengaturan ini di Cara Mengizinkan Eksekusi Skrip PowerShell di Windows 7. Namun, ini juga sesuatu yang tidak ingin Anda lakukan di sembarang komputer.
  3. Beberapa skrip PowerShell tidak akan berfungsi tanpa izin Administrator.
    Bahkan berjalan dengan akun tingkat Administrator, Anda masih perlu melewati Kontrol Akun Pengguna (UAC) untuk melakukan tindakan tertentu. Kami tidak ingin menonaktifkan ini, tetapi masih bagus ketika kami dapat membuatnya lebih mudah untuk ditangani.
  4. Beberapa pengguna mungkin telah menyesuaikan lingkungan PowerShell.
    Anda mungkin tidak akan sering menjumpai hal ini, tetapi ketika Anda melakukannya dapat membuat berjalan dan memecahkan masalah skrip Anda sedikit membuat frustrasi. Untungnya, kita bisa menyelesaikan ini tanpa membuat perubahan permanen juga.

Langkah 1: Klik dua kali untuk menjalankan.

Mari kita mulai dengan mengatasi masalah pertama - asosiasi file .PS1. Anda tidak dapat mengklik dua kali untuk menjalankan file .PS1, tetapi Anda dapat mengeksekusi file .BAT dengan cara itu. Jadi, kita akan menulis file batch untuk memanggil skrip PowerShell dari baris perintah untuk kita.

Jadi kita tidak perlu menulis ulang file batch untuk setiap skrip, atau setiap kali kita memindahkan skrip, ia akan menggunakan variabel referensi sendiri untuk membangun jalur file untuk skrip PowerShell. Untuk membuat ini berfungsi, file batch harus ditempatkan di folder yang sama dengan skrip PowerShell Anda dan memiliki nama file yang sama. Jadi, jika skrip PowerShell Anda disebut "MyScript.ps1", Anda ingin menamai file batch Anda "MyScript.bat" dan memastikannya berada di folder yang sama. Kemudian, taruh baris-baris ini dalam skrip batch:

@ECHO OFF PowerShell.exe -Command "& '% ~ dpn0.ps1'" JEDA

Jika bukan karena pembatasan keamanan lainnya di tempat, itu benar-benar semua yang diperlukan untuk menjalankan skrip PowerShell dari file batch. Bahkan, garis pertama dan terakhir terutama hanya masalah preferensi - ini adalah baris kedua yang benar-benar melakukan pekerjaan. Berikut uraiannya:

@ECHO OFF mematikan perintah echoing. Ini hanya membuat perintah lain Anda muncul di layar ketika file batch berjalan. Baris ini disembunyikan dengan menggunakan simbol (@) di depannya.

PowerShell.exe -Command “& '% ~ dpn0.ps1'” sebenarnya menjalankan skrip PowerShell. PowerShell.exe tentu saja dapat dipanggil dari jendela CMD apa pun atau file batch untuk meluncurkan PowerShell ke konsol kosong seperti biasa. Anda juga dapat menggunakannya untuk menjalankan perintah langsung dari file batch, dengan memasukkan parameter -Command dan argumen yang sesuai. Cara ini digunakan untuk menargetkan file .PS1 kami dengan variabel% ~ dpn0 khusus. Jalankan dari file batch,% ~ dpn0 mengevaluasi ke huruf drive, path folder, dan nama file (tanpa ekstensi) dari file batch. Karena file batch dan skrip PowerShell akan berada di folder yang sama dan memiliki nama yang sama,% ~ dpn0.ps1 akan menerjemahkan ke path file lengkap dari skrip PowerShell.

JEDA hanya menghentikan eksekusi batch dan menunggu input pengguna. Ini umumnya berguna untuk memiliki pada akhir file batch Anda, sehingga Anda memiliki kesempatan untuk meninjau output perintah apa pun sebelum jendela menghilang. Saat kami melakukan pengujian setiap langkah, kegunaan ini akan menjadi lebih jelas.

Jadi, file batch dasar sudah diatur. Untuk tujuan demonstrasi, file ini disimpan sebagai "D: \ Script Lab \ MyScript.bat" dan ada "MyScript.ps1" di folder yang sama. Mari kita lihat apa yang terjadi ketika kita mengklik dua kali MyScript.bat.

Jelas skrip PowerShell tidak berjalan, tetapi itulah yang diharapkan - kami hanya membahas yang pertama dari empat masalah kami, setelah semua. Namun, ada beberapa bagian penting yang ditunjukkan di sini:

  1. Judul jendela menunjukkan bahwa skrip batch berhasil meluncurkan PowerShell.
  2. Baris pertama dari output menunjukkan bahwa profil PowerShell kustom sedang digunakan. Ini adalah masalah potensial # 4, yang tercantum di atas.
  3. Pesan kesalahan menunjukkan pembatasan ExecutionPolicy berlaku. Itu masalah kita # 2.
  4. Bagian yang digarisbawahi dari pesan kesalahan (yang dilakukan secara native oleh output kesalahan PowerShell) menunjukkan skrip batch dengan benar menargetkan skrip PowerShell yang dimaksud (D: \ Script Lab \ MyScript.ps1). Jadi setidaknya kita tahu bahwa banyak yang berfungsi sebagaimana mestinya.

Profil, dalam hal ini, adalah skrip satu baris sederhana yang digunakan untuk demonstrasi ini untuk menghasilkan output setiap kali profil aktif. Anda dapat menyesuaikan profil PowerShell Anda sendiri untuk melakukan ini juga, jika Anda ingin menguji skrip ini sendiri. Cukup tambahkan baris berikut ke skrip profil Anda:

Menulis-output 'Custom PowerShell profile berlaku!'

The ExecutionPolicy pada sistem tes di sini diatur ke RemoteSigned. Ini memungkinkan eksekusi skrip yang dibuat secara lokal (seperti skrip profil), sementara memblokir skrip dari sumber luar kecuali ditandatangani oleh otoritas tepercaya. Untuk tujuan demonstrasi, perintah berikut digunakan untuk menandai MyScript.ps1 sebagai dari sumber eksternal:

Add-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Nilai "[ZoneTransfer] 'nZoneId = 3" -Stream' Zone.Identifier '

Itu mengatur aliran data Zone.Identifier alternatif pada MyScript.ps1 sehingga Windows akan berpikir file tersebut berasal dari Internet. Ini dapat dengan mudah dibalik dengan perintah berikut:

Clear-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone.Identifier'

Langkah 2: Berkeliling dengan ExecutionPolicy.

Mengelilingi pengaturan ExecutionPolicy, dari CMD atau skrip batch, sebenarnya cukup mudah. Kami hanya memodifikasi baris kedua skrip untuk menambahkan satu parameter lagi ke perintah PowerShell.exe.

PowerShell.exe -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"

Parameter -ExecutionPolicy dapat digunakan untuk memodifikasi ExecutionPolicy yang digunakan ketika Anda menelurkan sesi PowerShell baru. Ini tidak akan bertahan di luar sesi itu, jadi kita dapat menjalankan PowerShell seperti ini kapan pun kita butuhkan tanpa melemahkan postur keamanan umum sistem. Sekarang setelah kami memperbaikinya, mari kita coba lagi:

Sekarang skrip telah dieksekusi dengan benar, kita dapat melihat apa yang sebenarnya dilakukan. Ini memberi tahu kami bahwa kami menjalankan skrip sebagai pengguna Terbatas. Skrip ini sebenarnya dijalankan oleh akun dengan izin Administrator, tetapi Kontrol Akun Pengguna menghalangi. Meskipun rincian tentang bagaimana skrip memeriksa untuk akses Administrator berada di luar cakupan artikel ini, inilah kode yang digunakan untuk demonstrasi:

if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Tulis-Output 'Running as Administrator!' else Tulis-Output 'Running Limited!' Jeda

Anda juga akan melihat bahwa sekarang ada dua operasi "Jeda" dalam output skrip - satu dari skrip PowerShell, dan satu dari file batch. Alasannya akan lebih jelas pada langkah selanjutnya.

Langkah 3: Mendapatkan akses Administrator.

Jika skrip Anda tidak menjalankan perintah apa pun yang memerlukan peningkatan, dan Anda cukup yakin Anda tidak perlu khawatir tentang profil khusus siapa pun yang menghalangi Anda, Anda dapat melewati sisa ini. Jika Anda menjalankan beberapa cmdlet Administrator level, Anda perlu bagian ini.

Sayangnya, tidak ada cara untuk memicu UAC untuk elevasi dari dalam file batch atau sesi CMD. Namun, PowerShell memungkinkan kami melakukan ini dengan Start-Process. Ketika digunakan dengan "-Verb RunAs" dalam argumennya, Start-Process akan mencoba meluncurkan aplikasi dengan izin Administrator. Jika sesi PowerShell belum terangkat, ini akan memicu prompt UAC. Untuk menggunakan ini dari file batch untuk meluncurkan skrip kami, kami akhirnya akan menghasilkan dua proses PowerShell - satu untuk menjalankan Start-Process dan lainnya, diluncurkan oleh Start-Process, untuk menjalankan skrip. Baris kedua dari file batch perlu diubah menjadi ini:

PowerShell.exe -Command "& Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "' -Verb RunAs"

Ketika file batch dijalankan, baris pertama output yang akan kita lihat adalah dari skrip profil PowerShell. Kemudian, akan ada prompt UAC ketika Start-Process mencoba meluncurkan MyScript.ps1.

Setelah mengklik melalui prompt UAC, instance PowerShell baru akan muncul. Karena ini adalah contoh baru, tentu saja, kita akan melihat lagi pemberitahuan skrip profil. Kemudian, MyScript.ps1 berjalan dan kita melihat bahwa kita memang berada dalam sesi yang ditinggikan.

Dan ada alasan kami memiliki dua jeda di sini juga. Jika tidak untuk yang ada di skrip PowerShell, kita tidak akan pernah melihat output skrip - jendela PowerShell akan muncul dan menghilang begitu skrip selesai dijalankan. Dan tanpa jeda dalam file batch, kita tidak akan dapat melihat apakah ada kesalahan meluncurkan PowerShell di tempat pertama.

Langkah 4: Dapatkan profil Custom PowerShell.

Mari singkirkan pemberitahuan profil khusus jahat itu sekarang, oke? Di sini, hampir tidak ada gangguan, tetapi jika profil PowerShell pengguna mengubah pengaturan default, variabel, atau fungsi dengan cara yang mungkin tidak Anda antisipasi dengan skrip Anda, itu bisa sangat merepotkan. Lebih mudah untuk menjalankan skrip Anda tanpa profil sepenuhnya sehingga Anda tidak perlu khawatir tentang hal ini. Untuk melakukan itu, kita hanya perlu mengubah baris kedua file batch sekali lagi:

PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "' -Verb RunAs"

Menambahkan parameter -NoProfile ke kedua instance PowerShell yang diluncurkan oleh skrip itu berarti skrip profil pengguna akan sepenuhnya dilewati di kedua langkah dan skrip PowerShell kami akan berjalan dalam lingkungan default yang dapat diprediksi. Di sini, Anda dapat melihat tidak ada pemberitahuan profil khusus di salah satu cangkang yang dihasilkan.

Jika Anda tidak memerlukan hak Administrator dalam skrip PowerShell Anda, dan Anda telah melewatkan Langkah 3, Anda dapat melakukannya tanpa instance PowerShell kedua dan baris kedua file batch Anda akan terlihat seperti ini:

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"

Outputnya akan terlihat seperti ini:

(Tentu saja, untuk skrip non-Administrator, Anda dapat melakukannya tanpa jeda akhir-skrip di skrip PowerShell Anda pada titik ini juga karena semuanya ditangkap di jendela konsol yang sama dan akan ditahan di sana oleh jeda pada akhir file batch.)

File batch yang lengkap.

Tergantung pada apakah Anda memerlukan izin Administrator untuk skrip PowerShell Anda (dan Anda benar-benar tidak boleh meminta mereka jika Anda tidak) file batch akhir akan terlihat seperti salah satu dari dua di bawah ini.

Tanpa akses Admin:

@ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'" JEDA

Dengan akses Admin:

@ECHO OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "' -Verb RunAs" PAUSE

Ingatlah untuk meletakkan file batch dalam folder yang sama dengan skrip PowerShell yang ingin Anda gunakan, dan berikan nama yang sama. Kemudian, tidak peduli sistem apa yang Anda ambil file-file itu, Anda akan dapat menjalankan skrip PowerShell Anda tanpa harus berurusan dengan salah satu pengaturan keamanan pada sistem. Anda tentu saja dapat melakukan perubahan tersebut secara manual setiap waktu, tetapi ini akan menghemat masalah Anda dan Anda tidak perlu khawatir tentang mengembalikan perubahan nanti.

Referensi:

  • Menjalankan skrip PowerShell dari file batch - Blog Pemrograman Daniel Schroeder
  • Memeriksa izin Administrator di PowerShell - Hai, Scripting Guy! Blog