9Sep

PowerShell Komut Dosyalarını Çalıştırmak İçin Bir Toplu İş Dosyası Nasıl Kullanılır

Çeşitli nedenlerden ötürü, çoğunlukla güvenlikle ilgili olan PowerShell komut dosyaları, toplu komut dosyaları olabileceği gibi kolayca taşınabilir ve kullanılabilir değildir. Bununla birlikte, bu sorunlara geçici bir çözüm bulmak için PowerShell komut dosyalarımıza bir toplu iş komut dosyası ekleyebiliriz. Burada size bu sorun alanlarından birkaçını ve etrafında dolaşmak için bir toplu komut dosyası nasıl oluşturulacağını göstereceğiz.

Neden. PS1 dosyamı başka bir bilgisayara kopyalayıp çalıştıramıyorum?

Hedef sistem, istenen ayrıcalıklarla ve doğru ayarları kullanarak rasgele komut dosyalarının çalıştırılmasına izin vermek üzere önceden yapılandırılmış olmadıkça, bunu yapmaya çalıştığınızda bazı sorunlarla karşılaşabilirsiniz.

  1. PowerShell varsayılan olarak. PS1 dosya uzantısıyla ilişkilendirilmez.
    Bunu başlangıçta PowerShell Geek School serimizde gerçekleştirdik. Windows, PowerShell komut yorumlayıcısına göndermek yerine. PS1 dosyalarını varsayılan olarak Not Defteri ile ilişkilendirir. Bu, yanlışlıkla kötü amaçlı komut dosyalarının çift tıklanarak yürütülmesini önlemek içindir. Bu davranışı değiştirebileceğiniz yollar vardır, ancak muhtemelen bu bilgisayarların bir kısmı sizin kendi bilgisayarlarınız değilse, komut dosyalarınızı taşıdığınız her bilgisayarda yapmak istediğiniz bir şey değildir.
  2. PowerShell, varsayılan olarak harici komut dosyası yürütülmesine izin vermiyor.
    PowerShell'deki ExecutionPolicy ayarı, Windows'un tüm sürümlerinde varsayılan olarak dış komut dosyalarının yürütülmesini engeller. Bazı Windows sürümlerinde, varsayılan komut dosyası yürütmesine izin vermez. Windows 7'de PowerShell Komut Dosyalarının Yürütülmesine İzin Verme Yöntemi'nde bu ayarı nasıl değiştireceğinizi gösterdik. Ancak, bu aynı zamanda yalnızca herhangi bir bilgisayarda yapmak istemediğiniz bir şeydir.
  3. Bazı PowerShell komut dosyaları Yönetici izinleri olmadan çalışmaz.
    Hatta bir Yönetici seviyesi hesabı ile çalışıyorsa da, bazı işlemleri gerçekleştirmek için Kullanıcı Hesabı Denetimi( UAC) 'ni kullanmanız gerekir. Bunu devre dışı bırakmak istemiyoruz, ancak başa çıkmak biraz daha kolaylaştırabildiğimizde yine de hoşumuza gidiyor.
  4. Bazı kullanıcılar PowerShell ortamlarını özelleştirebilir.
    Muhtemelen buna sık sık girmeyeceksiniz, ancak bunu yaptığınızda komut dosyalarınızı çalıştırıp sorun gidermeyi biraz sinir bozucu hale getirebilirsiniz. Neyse ki, bunu da kalıcı bir değişiklik yapmadan da gerçekleştirebiliriz.

Adım 1: Çalıştırmak için çift tıklayın.

İlk sorun -. PS1 dosya ilişkilerine değinerek başlayalım..PS1 dosyalarını çalıştırmak için çift tıklatamazsınız, ancak. BAT dosyasını bu şekilde yürütebilirsiniz. Bunun için, komut satırından PowerShell komut dosyasını aramamız için bir toplu iş dosyası yazacağız.

Bu nedenle, her betik için toplu iş dosyasını yeniden yazmak zorunda kalmamakta veya bir betiği her dolaştıracağımız zaman, PowerShell betiğinin dosya yolunu oluşturmak için kendi kendine atıf yapan bir değişkeni kullanacağız. Bu işi yapmak için, toplu iş dosyasının PowerShell komut dosyanızla aynı klasöre yerleştirilmesi ve aynı dosya adına sahip olması gerekir. Yani, PowerShell komut dosyanız "MyScript.ps1" olarak adlandırılmışsa, toplu iş dosyanıza "MyScript.bat" adını vermek ve aynı klasörde olduğundan emin olmak istersiniz. Daha sonra, bu satırları toplu iş komut dosyasına koyun:

@ECHO OFF PowerShell.exe - Komutan "& '% ~ dpn0.ps1'" PAUSE

Eğer diğer güvenlik kısıtlamaları yerine getirilmemiş olsaydı, bu gerçekten çok şey olurdubir toplu iş dosyasından bir PowerShell komut dosyası çalıştırmak için gereken süre. Aslında, ilk ve son satırlar esas olarak yalnızca bir meselesidir - işi gerçekten yapan ikinci satırdır.İşte arıza:

@ECHO OFF komutu yankılarını kapatır. Bu, yalnızca toplu iş dosyası çalıştırıldığında diğer komutların ekranda görünmesini önler. Bu satır kendisinin önündeki at( @) sembolü kullanılarak gizlenmiştir.

PowerShell.exe - Komut "&'% ~ Dpn0.ps1' " aslında PowerShell komut dosyasını çalıştırır. PowerShell.exe elbette herhangi bir CMD penceresinden veya toplu iş dosyasından çağrılarak PowerShell'i her zamanki gibi çıplak bir konsolda başlatabilir. Komut parametresini ve uygun bağımsız değişkenleri ekleyerek komutları doğrudan bir toplu iş dosyasından çalıştırmak için kullanabilirsiniz. Bunun,. PS1 dosyamızı hedeflemek için kullanılan yolu özel% ~ dpn0 değişkeni ile. Bir toplu iş dosyasından çalıştırın,% ~ dpn0, toplu iş dosyasının sürücü harfine, klasör yoluna ve dosya adına( uzantı olmadan) değerlendirir. Toplu iş dosyası ve PowerShell komut dosyası aynı klasörde olacak ve aynı ada sahip olacaklarından% ~ dpn0.ps1, PowerShell komut dosyasının tam dosya yoluna çevrilecek.

PAUSE sadece toplu iş yürütmeyi duraklatır ve kullanıcı girişi için bekler. Bu, genellikle, toplu iş dosyalarınızın sonunda bulunması yararlıdır; böylece, pencere kaybolmadan önce herhangi bir komut çıktısını gözden geçirme şansınız olacaktır. Her adımı test ederken, bunun yararlılığı daha belirgin hale gelecektir.

Yani, temel toplu iş dosyası kuruldu. Demonstrasyon amaçlarıyla bu dosya "D: \ Script Lab \ MyScript.bat" olarak kaydedilir ve aynı klasörde bir "MyScript.ps1" bulunur. MyScript.bat'ı çift tıkladığımızda ne olacağını görelim.

Açıkçası PowerShell betiği çalışmadı, ancak bunun olması bekleniyor - yalnızca dört sorunumuzun ilkine değindik. Bununla birlikte, burada gösterilen bazı önemli bitler vardır:

  1. Pencere başlığı, toplu komut dosyasının PowerShell'i başarıyla başlattığını gösterir.
  2. Çıktıların ilk satırı, özel bir PowerShell profilinin kullanımda olduğunu gösterir. Bu, yukarıda listelenen potansiyel sorun 4'tür.
  3. Hata iletisi, yürürlükteki ExecutionPolicy kısıtlamalarını gösterir. Bizim sorunumuz 2.
  4. Hata mesajının altı çizili kısmı( doğal olarak PowerShell'in hata çıktısı ile yapılır), toplu iş komut dosyasının, amaçlanan PowerShell komut dosyasını( D: \ Script Lab \ MyScript.ps1) doğru şekilde hedeflediğini gösterir. Dolayısıyla, en azından o kadarının doğru bir şekilde çalıştığını biliyoruz.

Profil, bu durumda, bu gösteri profili etkin olduğunda çıktının üretilmesi için kullanılan basit tek satırlı bir betiktir. Bu komut dosyalarını kendiniz test etmek istiyorsanız, kendi PowerShell profilinizi de bunu yapmak için özelleştirebilirsiniz. Profil dosyanıza aşağıdaki satırı ekleyin:

Yazma Çıktısı 'Gerçekte Özel PowerShell profili etkin!'

Burada test sistemindeki ExecutionPolicy RemoteSigned olarak ayarlandı.Bu, yerel olarak( profili komut dosyası gibi) oluşturulan komut dosyalarının yürütülmesine izin verirken, komut dosyaları güvenilir bir makam tarafından imzalanmadıkça dış kaynaklardan engellenir. Gösteri amaçlı olarak, MyScript.ps1'i harici bir kaynaktan olmak üzere işaretlemek için aşağıdaki komut kullanılır:

Add-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Value "[ZoneTransfer]` nZoneId = 3 "-Akış 'Zone. Identifier'

Bu, Windows'un dosyanın İnternet'ten geldiğini düşünmesini sağlamak için MyScript.ps1'de Zone. Identifier alternatif veri akışını ayarlar. Aşağıdaki komutla kolayca tersine çevrilebilir:

Temizle-İçeriği -Path 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone. Identifier'

Adım 2: ExecutionPolicy'le başa çıkma.

CMD'den veya toplu iş dosyasından ExecutionPolicy ayarına geçmek aslında oldukça kolaydır. PowerShell.exe komutuna bir parametre daha eklemek için komut satırının ikinci satırını değiştirelim.

PowerShell.exe -ExecutionPolicy Bypass - Komut "ve '% ~ dpn0.ps1'"

-ExecutionPolicy parametresi, yeni bir PowerShell oturumu oluşturulurken kullanılan ExecutionPolicy'i değiştirmek için kullanılabilir. Bu oturumun ötesinde olmaz, bu nedenle sistemin genel güvenlik durumunu zayıflatmadan ihtiyaç duyduğumuzda PowerShell'i çalıştırabiliriz.Şimdi bunu düzelttik artık, birşeyler atalım:

Betiğin düzgün yürütülmüş olduğundan, aslında ne yaptığını görebiliyoruz. Komut dosyasını Sınırlı bir kullanıcı olarak çalıştırdığımızı bize bildiriyor. Komut dosyası aslında Yönetici izinlerine sahip bir hesap tarafından çalıştırılıyor ancak Kullanıcı Hesabı Denetimi yoluna giriyor. Komut dosyasının Yönetici erişimini denetleme şeklindeki ayrıntılar bu makalenin kapsamı dışındadır ancak gösteri için kullanılan kod şu şekildedir:

if( ([Security. Principal. WindowsPrincipal] [Security. Principal. WindowsIdentity]: : GetCurrent() ) IsInRole( [Security. Principal. WindowsBuiltInRole] "Administrator")){ Write-Output 'Yönetici Olarak Çalıştırılıyor!'} Else{ Write-Output 'Running Limited!' Duraklat

Ayrıca şu an ikiKomut dosyası çıktısındaki "Duraklat" işlemleri - bir tanesi PowerShell komut dosyası ve biri de toplu iş dosyasından. Bunun nedeni bir sonraki adımda daha belirgindir.

Adım 3: Yönetici erişimini edinme.

Eğer senaryonun yükseltme gerektiren herhangi bir komut çalıştırmaması durumunda, başkalarının özel profillerinin yolunu bulması konusunda endişelenmenize gerek olmayacağından emin olursanız, geri kalanı atlayabilirsiniz. Yine de bazı Yönetici düzeyindeki cmdlet'lerini çalıştırıyorsanız, bu parçaya ihtiyacınız olacaktır.

Ne yazık ki, bir toplu iş dosyası veya CMD oturumu içinde UAC'yi yükseltirken tetiklemek mümkün değildir. Bununla birlikte, PowerShell bunu Başlama İşlemiyle yapmamıza izin veriyor. Argümanlarında "-Verb RunAs" kullanıldığında Start-Process, Yönetici izinlerine sahip bir uygulamayı başlatmayı deneyecektir. PowerShell oturumu yükseltilmemişse, bu bir UAC istemi tetikler. Bunu komut dosyamızı başlatmak için toplu iş dosyasından kullanmak için iki tane PowerShell işlemi - biri Başlama İşlemi'ni başlatmak için diğeri de Başlama İşlemi tarafından başlatılan - komut dosyasını çalıştırmak için üreteceğiz. Toplu iş dosyasının ikinci satırı şu şekilde değiştirilmelidir:

PowerShell.exe -Command "&{ Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "' -VerbRunAs} "

Toplu iş dosyası çalıştırıldığında, gördüğümüz ilk çıktı satırı PowerShell profil komut dosyasından alınır. Sonra, Start-Process MyScript.ps1'i başlatmaya çalıştığında bir UAC istemi olacaktır.

UAC komutunu tıklattıktan sonra, yeni bir PowerShell örneği ortaya çıkacaktır. Elbette bu yeni bir örnek olduğundan, profil komut dosyası uyarısını tekrar göreceğiz. Ardından, MyScript.ps1 çalışıyor ve gerçekten yüksek bir oturum olduğumuzu görüyoruz.

Ve burada da iki duraklamamızın nedeni var. PowerShell komut dosyasındaki komut dosyası için değilse, komut dosyasının çıktısını asla göremezdik - komut dosyası çalışmaya başlar bitmez PowerShell penceresi açılır ve kaybolur. Ve toplu iş dosyasındaki duraklama olmadan, ilk önce PowerShell'i başlatırken herhangi bir hata olup olmadığını göremezdik.

4. Adım: Özel PowerShell profilleri edinme.

Şimdi bu kötü profil profilden kurtulalım, olur mu? Burada zorluklar bile görülmez, ancak bir kullanıcının PowerShell profili varsayılan ayarları, değişkenleri veya işlevleri senaryonuzla öngörmediğiniz şekilde değiştirirse, gerçekten zahmetli olabilirler. Senaryonuzu tamamen çalıştırmadan çalıştırmak çok daha basit, dolayısıyla bu konuda endişelenmenize gerek yok. Bunu yapmak için, toplu iş dosyasının ikinci satırını bir kez daha değiştirmemiz yeterlidir:

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

Komut dosyası tarafından başlatılan PowerShell'in her iki örneğine de -NoProfile parametresi eklenmesi, kullanıcının profil komut dosyasının her iki adımda da tamamen atlanacağı ve PowerShell komut dosyasınınOldukça öngörülebilir bir varsayılan ortam. Burada, oluşturulan kabukların hiçbirinde özel profil bildirimi olmadığını görebilirsiniz.

PowerShell komut dosyanıza Yönetici haklarına ihtiyaç duymazsanız ve 3. Adım'ı atladıysanız, ikinci PowerShell örneği olmadan yapabilirsiniz ve toplu iş dosyanızın ikinci satırı şu şekilde görünmelidir:

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

Çıktı şu şekilde görünecek:

( Tabii ki, Yönetici dışı komutlar için, PowerShell komut dosyanıza komut sonu duraklatma yapmadan yapabilirsinizher şey aynı konsol penceresinde yakalandığından ve toplu iş dosyasının sonundaki duraklamayla yine de tutulacağı için bu noktada.)

Tamamlanmış toplu iş dosyaları.

PowerShell komut dosyanız için Yönetici izinlerine ihtiyacınız olup olmadığına bağlı olarak( ve yapmamanız durumunda onlardan gerçekten istemeniz gerekmemelidir), son toplu iş dosyasının aşağıdaki ikisinden biri gibi görünmesi gerekir.

Yönetici erişimi olmadan:

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

Yönetici erişimi olan:

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

Toplu iş dosyasını istediğiniz PowerShell komut dosyası ile aynı klasöre koymayı unutmayıniçin kullanmak ve ona aynı adı vermek. Ardından, bu dosyaları hangi sisteme alırsanız yapın, PowerShell komut dosyanızı sistemdeki herhangi bir güvenlik ayarıyla karıştırmanız gerekmeden çalıştırabilirsiniz. Bu değişiklikleri her seferinde manuel olarak yapabilirsiniz, ancak bu sizi zora sokar ve değişiklikleri sonradan geri almayı düşünmek zorunda kalmazsınız.

Kaynaklar:

  • Bir toplu iş dosyasından PowerShell komut dosyalarını çalıştırma - Daniel Schroeder'in Programlama Blogu
  • PowerShell'de Yönetici İzinleri Kontrolü - Hey, Scripting Guy! Blog