Hello Stack Community :)
Saya punya tujuan sederhana. Saya ingin memulai beberapa Skrip PowerShell dari Skrip Powershell lain, tetapi ada 3 ketentuan:
- Saya harus lulus kredensial (eksekusi terhubung ke database yang memiliki pengguna tertentu)
- Itu harus mengambil beberapa Parameter
- Saya ingin melewatkan output ke dalam variabel
Ada sejenis pertanyaan link . Tetapi jawabannya adalah menggunakan file sebagai cara untuk berkomunikasi antara 2 PS Script. Saya hanya ingin menghindari konflik akses. @ Pembaruan: Skrip Utama akan memulai beberapa skrip lainnya. jadi solusi dengan file bisa rumit, jika eksekusi akan dilakukan dari beberapa pengguna secara bersamaan.
Script1.ps1 adalah skrip yang harus memiliki string sebagai output. (Untuk lebih jelasnya, ini adalah naskah fiktif, yang asli memiliki 150 Baris, jadi saya hanya ingin membuat contoh)
param(
[String]$DeviceName
)
#Some code that needs special credentials
$a = "Device is: " + $DeviceName
$a
ExecuteScripts.ps1 harus memohon yang satu dengan 3 kondisi yang disebutkan di atas
Saya mencoba beberapa solusi. Ini untuk contoh:
$arguments = "C:\..\script1.ps1" + " -ClientName" + $DeviceName
$output = Start-Process powershell -ArgumentList $arguments -Credential $credentials
$output
Saya tidak mendapatkan hasil dari itu dan saya tidak bisa begitu saja memanggil skrip
&C:\..\script1.ps1 -ClientName PCPC
Karena saya tidak bisa mengirimkan -Credential
parameter ke sana ..
Terima kasih sebelumnya!
sumber
Jawaban:
catatan:
Solusi berikut ini berfungsi dengan program eksternal apa pun , dan menangkap output sebagai teks .
Untuk memanggil instance PowerShell lain dan menangkap outputnya sebagai objek kaya (dengan keterbatasan), lihat solusi varian di bagian bawah atau pertimbangkan jawaban Mathias R. Jessen yang bermanfaat , yang menggunakan PowerShell SDK .
Berikut adalah bukti konsep yang didasarkan pada penggunaan langsung tipe
System.Diagnostics.Process
danSystem.Diagnostics.ProcessStartInfo
.NET untuk menangkap output proses dalam memori (sebagaimana dinyatakan dalam pertanyaan Anda,Start-Process
bukan opsi, karena hanya mendukung menangkap keluaran dalam file , seperti yang ditunjukkan dalam jawaban ini ) :catatan:
Karena berjalan sebagai pengguna yang berbeda, ini hanya didukung pada Windows (pada .NET Core 3.1), tetapi di kedua edisi PowerShell di sana.
Karena perlu dijalankan sebagai user yang berbeda dan perlu untuk menangkap output,
.WindowStyle
tidak dapat digunakan untuk menjalankan perintah tersembunyi (karena menggunakan.WindowStyle
membutuhkan.UseShellExecute
untuk menjadi$true
, yang tidak sesuai dengan persyaratan ini); Namun, karena semua output ditangkap , pengaturan.CreateNoNewWindow
untuk$true
secara efektif menghasilkan eksekusi tersembunyi.Di atas menghasilkan sesuatu seperti berikut, menunjukkan bahwa proses berhasil berjalan dengan identitas pengguna yang diberikan:
Karena Anda memanggil instance PowerShell lain , Anda mungkin ingin memanfaatkan kemampuan PowerShell CLI untuk merepresentasikan output dalam format CLIXML, yang memungkinkan deserialisasi output menjadi objek kaya , meskipun dengan ketelitian jenis terbatas , seperti dijelaskan dalam jawaban terkait ini .
Output di atas menghasilkan sesuatu seperti yang berikut, menunjukkan bahwa
[datetime]
instance (System.DateTime
) output olehGet-Date
deserialized seperti:sumber
Start-Process
akan menjadi pilihan terakhir saya untuk menggunakan PowerShell dari PowerShell - terutama karena semua I / O menjadi string dan bukan objek (deserialized).Dua alternatif:
1. Jika pengguna adalah admin lokal dan PSRemoting dikonfigurasi
Jika sesi jarak jauh terhadap mesin lokal (sayangnya terbatas pada admin lokal) adalah pilihan, saya pasti akan mengikuti
Invoke-Command
:$strings
akan berisi hasil.2. Jika pengguna bukan admin pada sistem target
Anda dapat menulis sendiri "hanya-lokal
Invoke-Command
" dengan memutar runspace out-of-proses dengan:PowerShellProcessInstance
, di bawah login yang berbedaSaya mengumpulkan fungsi seperti di bawah ini, lihat komentar inline untuk walk-through:
Kemudian gunakan seperti ini:
sumber
rcv.ps1
eksekusi dari skrip lain:
keluaran:
sumber
Apa yang dapat Anda lakukan berikut ini untuk meneruskan parameter ke skrip ps1.
Script pertama dapat berupa origin.ps1 tempat kami menulis:
Script tujuan dest.ps1 dapat memiliki kode berikut untuk menangkap variabel
Dan hasilnya akan seperti itu
sumber
-Credential $credentials
parameter ke eksekusi ini dan mendapatkan output dari itu menjadi variabel. Ps1. Script im executing adalah melemparkan string kata menghanguskan di akhir. Lihat saja cara saya melakukannyaStart-process
tetapi fungsi ini tidak menghasilkan keluaran$output
variabel, itu NULL. Ide lain yang datang dari @ mklement0 adalah untuk menyimpan output ke file. Tetapi dalam kasus saya ini akan menyebabkan sejumlah besar file di satu tempat. Semua dibuat dari pengguna yang berbeda dengan skrip yang berbeda