Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Kısa süre önce ikili modül olarak uygulamak istediğim modülle ilgili bir fikrim vardı. PowerShell Standart Kitaplığı kullanarak henüz bir tane oluşturmadım, bu yüzden bu iyi bir fırsat gibi geldi. Bu modülü herhangi bir engel olmadan oluşturmak için platformlar arası ikili modül oluşturma kılavuzu kullandım. Aynı süreç boyunca yürüyeceğiz ve yol boyunca biraz ek yorum ekleyeceğim.
Not
Bu makalenin özgün sürümü@KevinMarquettetarafından yazılan blogda yer almıştır. PowerShell ekibi, bu içeriği bizimle paylaştığı için Kevin'e teşekkür ederiz. Lütfen PowerShellExplained.comadresinde blogunu inceleyin.
PowerShell Standart Kitaplığı nedir?
PowerShell Standart Kitaplığı, hem PowerShell hem de Windows PowerShell 5.1'de çalışan platformlar arası modüller oluşturmamıza olanak tanır.
Neden ikili modüller?
C# dilinde bir modül yazarken PowerShell cmdlet'lerine ve işlevlerine kolay erişimden vazgeçersiniz. Ancak, çok fazla başka PowerShell komutuna bağımlı olmayan bir modül oluşturuyorsanız performans avantajı önemli olabilir. PowerShell, bilgisayar için değil yönetici için iyileştirilmiştir. C# moduna geçerek PowerShell tarafından eklenen ek yükü ortadan kaldırmaya başlarsınız.
Örneğin, JSON ve karma tablolarla yoğun bir şekilde çalışan kritik bir sürecimiz bulunmaktadır. PowerShell'i olabildiğince iyileştirdik, ancak işlemin tamamlanması 12 dakika sürer. Modülde zaten çok sayıda C# stili PowerShell vardı. Bu, ikili modüle dönüştürmeyi temiz ve basit hale getirir. İkili modüle dönüştürerek işlem süresini 12 dakikadan dört dakikanın altına düşürdük.
Karma modüller
İkili cmdlet'leri PowerShell gelişmiş işlevleriyle karıştırabilirsiniz. Betik modülleri hakkında bildiğiniz her şey aynı şekilde geçerlidir. Boş psm1
dosyası eklenir, böylece daha sonra başka PowerShell işlevleri ekleyebilirsiniz.
Oluşturduğum derlenmiş cmdlet'lerin neredeyse tümü ilk olarak PowerShell işlevleri olarak başladı. tüm ikili modüllerimiz gerçekten karma modüllerdir.
Betik oluşturma
Derleme betiğini burada basit tuttum. Genellikle CI/CD işlem hattımın bir parçası olarak büyük bir Invoke-Build
komut dosyası kullanıyorum. Pester testlerini çalıştırma, PSScriptAnalyzer çalıştırma, sürüm oluşturma ve PSGallery'de yayımlama gibi daha fazla sihir yapar. Modüllerim için bir derleme betiği kullanmaya başladığımda, buna eklenecek birçok şey bulabildim.
Modülü planlama
Bu modülün planı, C# kodu için bir src
klasörü oluşturmak ve geri kalanını bir betik modülü için yaptığım gibi yapılandırmaktır. Bu, her şeyi bir Output
klasörüne derlemek için derleme betiği kullanmayı içerir. Klasör yapısı şöyle görünür:
MyModule
├───src
├───Output
│ └───MyModule
├───MyModule
│ ├───Data
│ ├───Private
│ └───Public
└───Tests
Başlangıç
İlk olarak klasörü oluşturmam ve git deposunu oluşturmam gerekiyor. Modül adı için yer tutucu olarak $module
kullanıyorum. Bu, gerekirse bu örnekleri yeniden kullanmanızı kolaylaştırmalıdır.
$module = 'MyModule'
New-Item -Path $module -Type Directory
Set-Location $module
git init
Ardından kök düzeyi klasörleri oluşturun.
New-Item -Path 'src' -Type Directory
New-Item -Path 'Output' -Type Directory
New-Item -Path 'Tests' -Type Directory
New-Item -Path $module -Type Directory
İkili modül kurulumu
Bu makale ikili modüle odaklanmıştır, bu nedenle burada başlayacağız. Bu bölüm Platformlar arası ikili modül oluşturma kılavuzundan örnekler alır. Daha fazla ayrıntıya ihtiyacınız varsa veya sorun yaşıyorsanız bu kılavuzu gözden geçirin.
yapmak istediğimiz ilk şey, yüklediğimiz dotnet core SDK sürümünü denetlemektir. 2.1.4 kullanıyorum ama devam etmeden önce 2.0.0 veya daha yeni bir sürüme sahip olmanız gerekir.
PS> dotnet --version
2.1.4
Bu bölüm için src
klasörü üzerinden çalışıyorum.
Set-Location 'src'
dotnet komutunu kullanarak yeni bir sınıf kitaplığı oluşturun.
dotnet new classlib --name $module
Bu, kitaplık projesini bir alt klasörde oluşturdu, ancak bu ek iç içe yerleştirme düzeyini istemiyorum. Bu dosyaları bir düzey yukarı taşıyacağım.
Move-Item -Path .\$module\* -Destination .\
Remove-Item $module -Recurse
Proje için .NET Core SDK sürümünü ayarlayın. 2.1 SDK'sına sahibim, bu nedenle 2.1.0
belirteceğim.
2.0 SDK kullanıyorsanız 2.0.0
kullanın.
dotnet new globaljson --sdk-version 2.1.0
Projeye PowerShell Standart KitaplığıNuGet paketi ekleyin. İhtiyacınız olan uyumluluk düzeyi için en son sürümü kullandığınızdan emin olun. Varsayılan olarak en son sürüme geçebilirim, ancak bu modülün PowerShell 3.0'dan daha yeni özelliklerden yararlanacağını sanmıyorum.
dotnet add package PowerShellStandard.Library --version 7.0.0-preview.1
Aşağıdakine benzer bir src klasörünüz olmalıdır:
PS> Get-ChildItem
Directory: \MyModule\src
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 7/14/2018 9:51 PM obj
-a---- 7/14/2018 9:51 PM 86 Class1.cs
-a---- 7/14/2018 10:03 PM 259 MyModule.csproj
-a---- 7/14/2018 10:05 PM 45 global.json
Artık projeye kendi kodumuzu eklemeye hazırız.
İkili cmdlet oluşturma
Bu başlangıç cmdlet'ini içerecek şekilde src\Class1.cs
'ı güncellememiz gerekiyor.
using System;
using System.Management.Automation;
namespace MyModule
{
[Cmdlet( VerbsDiagnostic.Resolve , "MyCmdlet")]
public class ResolveMyCmdletCommand : PSCmdlet
{
[Parameter(Position=0)]
public Object InputObject { get; set; }
protected override void EndProcessing()
{
this.WriteObject(this.InputObject);
base.EndProcessing();
}
}
}
Dosyayı sınıf adıyla eşleşecek şekilde yeniden adlandırın.
Rename-Item .\Class1.cs .\ResolveMyCmdletCommand.cs
Ardından modülümüzü derleyebiliriz.
PS> dotnet build
Microsoft (R) Build Engine version 15.5.180.51428 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 18.19 ms for C:\workspace\MyModule\src\MyModule.csproj.
MyModule -> C:\workspace\MyModule\src\bin\Debug\netstandard2.0\MyModule.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.19
Yeni cmdlet'imizi yüklemek için yeni dll'de Import-Module
çağırabiliriz.
PS> Import-Module .\bin\Debug\netstandard2.0\$module.dll
PS> Get-Command -Module $module
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Resolve-MyCmdlet 1.0.0.0 MyModule
Sisteminizde içeri aktarma işlemi başarısız olursa .NET'i 4.7.1 veya daha yeni bir sürüme güncelleştirmeyi deneyin. platformlar arası ikili modül oluşturma kılavuzu .NET'in eski sürümleri için .NET desteği ve uyumluluğu hakkında daha fazla ayrıntıya gider.
Modül bildirimi
Dll'yi içeri aktarıp çalışan bir modüle sahip olmamız çok güzel. Devam etmek ve bir modül bildirimi oluşturmak istiyorum. Daha sonra PSGallery'de yayımlamak istiyorsak bildirime ihtiyacımız var.
Projemizin kökünden bu komutu çalıştırarak ihtiyacımız olan modül bildirimini oluşturabiliriz.
$manifestSplat = @{
Path = ".\$module\$module.psd1"
Author = 'Kevin Marquette'
NestedModules = @('bin\MyModule.dll')
RootModule = "$module.psm1"
FunctionsToExport = @('Resolve-MyCmdlet')
}
New-ModuleManifest @manifestSplat
Ayrıca gelecekteki PowerShell işlevleri için boş bir kök modülü oluşturacağım.
Set-Content -Value '' -Path ".\$module\$module.psm1"
Bu sayede hem normal PowerShell işlevlerini hem de ikili cmdlet'leri aynı projede birleştirdim.
Modülün tamamını oluşturma
Her şeyi bir çıkış klasöründe derliyorum. Bunu yapmak için bir derleme betiği oluşturmamız gerekir. Normalde bunu bir Invoke-Build
betiğine eklerdim, ancak bu örnekte basit tutabiliriz. Bunu projenin kök dizinine bir build.ps1
ekleyin.
$module = 'MyModule'
Push-Location $PSScriptRoot
dotnet build $PSScriptRoot\src -o $PSScriptRoot\output\$module\bin
Copy-Item "$PSScriptRoot\$module\*" "$PSScriptRoot\output\$module" -Recurse -Force
Import-Module "$PSScriptRoot\Output\$module\$module.psd1"
Invoke-Pester "$PSScriptRoot\Tests"
Bu komutlar DLL'mizi oluşturur ve output\$module\bin
klasörümüze yerleştirir. Ardından diğer modül dosyalarını yerine kopyalar.
Output
└───MyModule
├───MyModule.psd1
├───MyModule.psm1
└───bin
├───MyModule.deps.json
├───MyModule.dll
└───MyModule.pdb
Bu noktada modülümüzü psd1 dosyasıyla içeri aktarabiliriz.
Import-Module ".\Output\$module\$module.psd1"
Buradan .\Output\$module
klasörünü $env:PSModulePath
dizinimize bırakabiliriz ve ihtiyacımız olduğunda komutumuzu otomatik olarak yükler.
Güncelleme: dotnet new PSModule
dotnet
aracının bir PSModule
şablonu olduğunu öğrendim.
Yukarıda özetlediğim tüm adımlar hala geçerli, ancak bu şablon pek çoğunu atlıyor. Hala iyileştirilen oldukça yeni bir şablon. Buradan daha iyi olmaya devam etmesini bekleyebilirsiniz.
Yükleme ve PSModule şablonunu bu şekilde kullanırsınız.
dotnet new -i Microsoft.PowerShell.Standard.Module.Template
dotnet new psmodule
dotnet build
Import-Module "bin\Debug\netstandard2.0\$module.dll"
Get-Module $module
Bu en az uygulanabilir şablon .NET SDK'sını, PowerShell Standart Kitaplığı'nı eklemeyi üstlenir ve projede örnek bir sınıf oluşturur. İnşa edip hemen çalıştırabilirsiniz.
Önemli ayrıntılar
Bu makaleyi sonlandırmadan önce, burada bahsetmeye değer diğer birkaç ayrıntı verilmiştir.
DLL'leri kaldırma
Bir ikili modül yüklendikten sonra, onu gerçekten kaldıramazsınız. DLL dosyası, siz onu boşaltana kadar kilitlidir. Geliştirme sırasında bu can sıkıcı olabilir çünkü her değişiklik yaptığınızda ve bunu oluşturmak istediğinizde dosya genellikle kilitlenir. Bunu çözmenin tek güvenilir yolu, DLL'yi yükleyen PowerShell oturumunu kapatmaktır.
VS Code penceresini yeniden yükleme eylemi
PowerShell geliştirme çalışmalarımın çoğunu VS Codeiçinde gerçekleştiriyorum. İkili modül (veya sınıflı bir modül) üzerinde çalışırken, her derlemede VS Code'ı yeniden yükleme alışkanlığı edindim.
Ctrl+Shift+P komut penceresini açar ve Reload Window
her zaman listemin en üstündedir.
İç içe PowerShell oturumları
Diğer bir seçenek iyi Pester test kapsamına sahip olmaktır. Ardından yeni bir PowerShell oturumu başlatmak, derlemeyi gerçekleştirmek, testleri çalıştırmak ve oturumu kapatmak için build.ps1 betiğini ayarlayabilirsiniz.
Yüklü modülleri güncelleştirme
Bu kilitleme, yerel olarak yüklenen modülünüzü güncelleştirmeye çalışırken can sıkıcı olabilir. Herhangi bir oturumda yüklüyse, onu arayıp bulup kapatmanız gerekir. PSGallery'den yükleme yaparken, modül sürümleme yeni sürümü farklı bir klasöre yerleştirdiği için bu sorun daha azdır.
Yerel bir PSGallery ayarlayabilir ve derlemenizin bir parçası olarak oraya yayımlayabilirsiniz. Ardından bu PSGallery'den yerel yüklemenizi yapın. Bu çok fazla iş gibi görünebilir, ancak bu bir docker kapsayıcısı başlatmak kadar basit olabilir. PsRepository için NuGet sunucusu kullanmagönderimde bunu yapmak için bir yol ele alıyorum.
Son düşünceler
Cmdlet oluşturmak için C# söz dizimine değinmedim, ancak Windows PowerShell SDKhakkında bolca belge mevcut. Kesinlikle daha ciddi bir C# alanına adım taşı olarak denemeye değer bir şey.
PowerShell