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.
Sık sık değiştirilmesi gereken PowerShell tek satırlık komutlar ve betikler, yeniden kullanılabilir işlevlere dönüştürmek için iyi birer adaydır.
Araç odaklı oldukları için mümkün olduğunca işlevler yazın. İşlevleri bir betik modülüne ekleyebilir, bu modülü $env:PSModulePath
tanımlanan bir konuma yerleştirebilir ve işlevleri kaydettiğiniz yeri bulmanıza gerek kalmadan işlevleri çağırabilirsiniz.
PowerShellGet modülünü kullanarak PowerShell modüllerinizi bir NuGet deposunda kolayca paylaşabilirsiniz.
PowerShellGet, PowerShell sürüm 5.0 ve üzeri ile gönderilir. Ayrıca PowerShell sürüm 3.0 ve üzeri için ayrı bir indirme olarak da kullanılabilir.
İşleri fazla karmaşık hale getirmeyin. Basit tutun ve bir görevi gerçekleştirmek için en basit yolu kullanın. Yeniden kullandığınız herhangi bir kodda diğer adlardan ve konumsal parametrelerden kaçının. Kodunuzu okunabilirlik için biçimlendirin. Değerleri sabit kodlamayın; parametreleri ve değişkenleri kullanın. Hiçbir şeye zarar vermese bile gereksiz kod yazmayın. Gereksiz karmaşıklık ekler. Herhangi bir PowerShell kodu yazarken ayrıntılara dikkat uzun bir yol kat eder.
Adlandırma
PowerShell'de işlevlerinizi adlandırırken, onaylanmış bir fiil ve tekil bir isimle birlikte Pascal case adı kullanın. PowerShell'de onaylanan fiillerin listesini almak için Get-Verb
çalıştırın. Aşağıdaki örnek, Get-Verb
sonuçlarını Fiil özelliğine göre sıralar.
Get-Verb | Sort-Object -Property Verb
Group özelliği, fiillerin nasıl kullanılacağı hakkında size bir fikir verir.
Verb Group
---- -----
Add Common
Approve Lifecycle
Assert Lifecycle
Backup Data
Block Security
Checkpoint Data
Clear Common
Close Common
Compare Data
Complete Lifecycle
Compress Data
Confirm Lifecycle
Connect Communications
Convert Data
ConvertFrom Data
ConvertTo Data
Copy Common
Debug Diagnostic
Deny Lifecycle
Disable Lifecycle
Disconnect Communications
Dismount Data
Edit Data
Enable Lifecycle
Enter Common
Exit Common
Expand Data
Export Data
Find Common
Format Common
Get Common
Grant Security
Group Data
Hide Common
Import Data
Initialize Data
Install Lifecycle
Invoke Lifecycle
Join Common
Limit Data
Lock Common
Measure Diagnostic
Merge Data
Mount Data
Move Common
New Common
Open Common
Optimize Common
Out Data
Ping Diagnostic
Pop Common
Protect Security
Publish Data
Push Common
Read Communications
Receive Communications
Redo Common
Register Lifecycle
Remove Common
Rename Common
Repair Diagnostic
Request Lifecycle
Reset Common
Resize Common
Resolve Diagnostic
Restart Lifecycle
Restore Data
Resume Lifecycle
Revoke Security
Save Data
Search Common
Select Common
Send Communications
Set Common
Show Common
Skip Common
Split Common
Start Lifecycle
Step Common
Stop Lifecycle
Submit Lifecycle
Suspend Lifecycle
Switch Common
Sync Data
Test Diagnostic
Trace Diagnostic
Unblock Security
Undo Common
Uninstall Lifecycle
Unlock Common
Unprotect Security
Unpublish Data
Unregister Lifecycle
Update Data
Use Other
Wait Lifecycle
Watch Common
Write Communications
PowerShell işlevleriniz için onaylı bir fiil kullanmak önemlidir. Onaylanmamış fiilleri olan işlevler içeren modüller, PowerShell oturumuna aktarıldığında bir uyarı iletisi oluşturur. Bu uyarı iletisi, işlevlerinizin profesyonel görünmemesini sağlar. Onaylanmamış fiiller işlevlerinizin bulunabilirliğini de sınırlar.
Basit bir işlev
PowerShell'de bir işlev, function anahtar kelimesi, ardından işlev adı ve bir açma-kapama küme ayracı ({ }
) ile tanımlanır. İşlevin yürüttüğü kod bu küme parantezleri içinde bulunur.
function Get-Version {
$PSVersionTable.PSVersion
}
Aşağıdaki örnekte gösterilen işlev, PowerShell sürümünü döndüren basit bir örnektir.
Get-Version
Major Minor Build Revision
----- ----- ----- --------
5 1 14393 693
İşlevleriniz için Get-Version
gibi genel bir ad kullandığınızda, adlandırma çakışmaları olabilir. Gelecekte eklenen varsayılan komutlar veya başkalarının yazabileceği komutlar bunlarla çakışabilir. Adlandırma çakışmalarını önlemeye yardımcı olmak için işlev adlarınızın isim bölümüne ön ek ekleyin. Örneğin: <ApprovedVerb>-<Prefix><SingularNoun>
.
Aşağıdaki örnekte PS
ön eki kullanılır.
function Get-PSVersion {
$PSVersionTable.PSVersion
}
Bu işlev, adın dışında bir öncekiyle aynıdır.
Get-PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 14393 693
Bir isme ön ek ekleseniz bile ad çakışması yaşayabilirsiniz. İşlev isimlerime baş harflerimin ön eklerini eklemeyi seviyorum. Bir standart geliştirin ve buna bağlı kalın.
function Get-MrPSVersion {
$PSVersionTable.PSVersion
}
Bu işlev, diğer PowerShell komutlarıyla adlandırma çakışmalarını önlemek için daha benzersiz bir ad kullanmak dışında önceki iki işlevden farklı değildir.
Get-MrPSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 14393 693
Belleğe yüklendikten sonra İşlev PSDrive'da işlevleri görebilirsiniz.
Get-ChildItem -Path Function:\Get-*Version
CommandType Name Version
----------- ---- -------
Function Get-Version
Function Get-PSVersion
Function Get-MrPSVersion
Bu işlevleri geçerli oturumunuzdan kaldırmak istiyorsanız, bunları PSDrive
Get-ChildItem -Path Function:\Get-*Version | Remove-Item
İşlevlerin gerçekten kaldırıldığını doğrulayın.
Get-ChildItem -Path Function:\Get-*Version
İşlevler bir modülün parçası olarak yüklendiyse, bunları kaldırmak için modülü kaldırabilirsiniz.
Remove-Module -Name <ModuleName>
Remove-Module
cmdlet'i geçerli PowerShell oturumunuzda PowerShell modüllerini bellekten kaldırır. Bunları sisteminizden veya diskinizde kaldırmaz.
Parametreler
Değerleri statik olarak atamayın. Bunun yerine parametreleri ve değişkenleri kullanın. Parametrelerinizi adlandırırken, mümkün olduğunda parametre adlarınız için varsayılan cmdlet'lerle aynı adı kullanın.
Aşağıdaki işlevde, parametre adı için Computer, ServerNameveya Host değil, ComputerName kullandığıma dikkat edin. ComputerName kullanılması, parametre adını varsayılan cmdlet'ler gibi parametre adı ve büyük/küçük harfle eşleşecek şekilde standartlaştırır.
function Test-MrParameter {
param (
$ComputerName
)
Write-Output $ComputerName
}
Aşağıdaki işlev sisteminizdeki tüm komutları sorgular ve belirli parametre adlarıyla sayıyı döndürür.
function Get-MrParameterCount {
param (
[string[]]$ParameterName
)
foreach ($Parameter in $ParameterName) {
$Results = Get-Command -ParameterName $Parameter -ErrorAction SilentlyContinue
[pscustomobject]@{
ParameterName = $Parameter
NumberOfCmdlets = $Results.Count
}
}
}
Aşağıdaki sonuçlarda görebileceğiniz gibi, ComputerName parametresine sahip 39 komut. Computer, ServerName, Hostveya Machinegibi parametreleri olan komut yoktur.
Get-MrParameterCount -ParameterName ComputerName, Computer, ServerName,
Host, Machine
ParameterName NumberOfCmdlets
------------- ---------------
ComputerName 39
Computer 0
ServerName 0
Host 0
Machine 0
Parametre adlarınız için varsayılan cmdlet'lerle aynı büyük harf kullanımını yapın. Örneğin, ComputerName
değil computername
kullanın. Bu adlandırma düzeni, PowerShell'i bilen kişilerin işlevlerinizi bulmasına ve varsayılan cmdlet'ler gibi görünmesine yardımcı olur.
param
deyimi bir veya daha fazla parametre tanımlamanızı sağlar. Virgül (,
), parametre tanımlarını ayırır. Daha fazla bilgi için bkz. about_Functions_Advanced_Parameters.
Gelişmiş işlevler
PowerShell'de bir işlevi gelişmiş bir işleve dönüştürmek basittir. İşlev ile gelişmiş işlev arasındaki farklardan biri, gelişmiş işlevlerin otomatik olarak eklenen ortak parametrelere sahip olmasıdır. Yaygın parametreler
Önceki bölümde kullanılan Test-MrParameter
işleviyle başlayın.
function Test-MrParameter {
param (
$ComputerName
)
Write-Output $ComputerName
}
Ortak parametreleri görmenin birkaç farklı yolu vardır. Bunlardan biri, söz dizimini Get-Command
ile görüntülemektir.
Get-Command -Name Test-MrParameter -Syntax
Test-MrParameter
işlevinin ortak parametreleri olmadığını fark edin.
Test-MrParameter [[-ComputerName] <Object>]
Bir diğeri ise Get-Command
'un parametreler özelliğine inmek.
(Get-Command -Name Test-MrParameter).Parameters.Keys
ComputerName
İşlevi gelişmiş bir işleve dönüştürmek için CmdletBinding
özniteliğini ekleyin.
function Test-MrCmdletBinding {
[CmdletBinding()] # Turns a regular function into an advanced function
param (
$ComputerName
)
Write-Output $ComputerName
}
CmdletBinding
belirttiğinizde, ortak parametreler otomatik olarak eklenir.
CmdletBinding
bir param
bloğu gerektirir, ancak param
bloğu boş olabilir.
Get-Command -Name Test-MrCmdletBinding -Syntax
Test-MrCmdletBinding [[-ComputerName] <Object>] [<CommonParameters>]
Get-Command
'nin parameters özelliğinin detayına inmek, ortak olanlar da dahil olmak üzere gerçek parametre adlarını gösterir.
(Get-Command -Name Test-MrCmdletBinding).Parameters.Keys
ComputerName
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
İşlemDestekler
SupportsShouldProcess
özelliği, WhatIf ve Confirm risk azaltma parametrelerini ekler. Bu parametreler yalnızca değişiklik yapacak komutlar için gereklidir.
function Test-MrSupportsShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param (
$ComputerName
)
Write-Output $ComputerName
}
Şimdi WhatIf ve Confirm parametrelerinin olduğunu fark edin.
Get-Command -Name Test-MrSupportsShouldProcess -Syntax
Test-MrSupportsShouldProcess [[-ComputerName] <Object>] [-WhatIf] [-Confirm]
[<CommonParameters>]
Bir kez daha Get-Command
kullanarak, yaygın olanlar da dahil olmak üzere gerçek parametre adlarının listesini döndürebilir, ayrıca WhatIf ve Confirmkomutlarını kullanabilirsiniz.
(Get-Command -Name Test-MrSupportsShouldProcess).Parameters.Keys
ComputerName
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
WhatIf
Confirm
Parametre doğrulama
Girişi erken doğrula. Geçerli giriş olmadan tamamlanamadıklarında kodunuzun bir yolda devam etmesine izin verme.
Parametreler için kullanılan değişkenler için her zaman bir veri türü belirtin. Aşağıdaki örnekte, String, ComputerName parametresinin veri türü olarak belirtilir. Bu doğrulama, ComputerName parametresi için yalnızca tek bir bilgisayar adının belirtilmesine izin verecek şekilde sınırlar.
function Test-MrParameterValidation {
[CmdletBinding()]
param (
[string]$ComputerName
)
Write-Output $ComputerName
}
Birden fazla bilgisayar adı belirtilirse bir hata oluşturulur.
Test-MrParameterValidation -ComputerName Server01, Server02
Test-MrParameterValidation : Cannot process argument transformation on
parameter 'ComputerName'. Cannot convert value to type System.String.
At line:1 char:42
+ Test-MrParameterValidation -ComputerName Server01, Server02
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Test-MrParameterValidation]
, ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Test-MrP
arameterValidation
Geçerli tanımla ilgili sorun, ComputerName parametresinin değerinin atlanmasının geçerli olmasıdır, ancak işlevin başarıyla tamamlanması için bir değer gerekir. Bu senaryo, Mandatory
parametre özniteliğinin yararlı olduğu senaryodur.
Aşağıdaki örnekte kullanılan söz dizimi PowerShell sürüm 3.0 ve üzeri ile uyumludur.
[Parameter(Mandatory=$true)]
, işlevi PowerShell sürüm 2.0 veya üzeriyle uyumlu hale getirmek için belirtilebilir.
function Test-MrParameterValidation {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$ComputerName
)
Write-Output $ComputerName
}
Artık ComputerName gerekli olduğuna göre, belirtilmemişse işlev bir tane ister.
Test-MrParameterValidation
cmdlet Test-MrParameterValidation at command pipeline position 1
Supply values for the following parameters:
ComputerName:
ComputerName parametresi için birden fazla değere izin vermek istiyorsanız, Dize veri türünü kullanın, ancak bir dize dizisine izin vermek için veri türüne köşeli ayraçlar ([]
) ekleyin.
function Test-MrParameterValidation {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string[]]$ComputerName
)
Write-Output $ComputerName
}
Belirtilmemişse, ComputerName parametresi için varsayılan bir değer belirtmek isteyebilirsiniz.
Sorun, varsayılan değerlerin zorunlu parametrelerle kullanılamayabilmesidir. Bunun yerine, varsayılan değerle ValidateNotNullOrEmpty
parametre doğrulama özniteliğini kullanın.
Varsayılan bir değer ayarlarken bile statik değerleri kullanmamaya çalışın. Aşağıdaki örnekte, $env:COMPUTERNAME
varsayılan değer olarak kullanılır ve bu değer sağlanmazsa otomatik olarak yerel bilgisayar adına çevrilir.
function Test-MrParameterValidation {
[CmdletBinding()]
param (
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = $env:COMPUTERNAME
)
Write-Output $ComputerName
}
Ayrıntılı çıkış
Satır içi açıklamalar, karmaşık kod yazıyorsanız yararlıdır, ancak kullanıcılar koda bakmadıkları sürece bunları görmez.
Aşağıdaki örnekteki işlevin foreach
döngüsünde satır içi bir açıklaması vardır. Bu açıklamayı bulmak zor olmasa da işlevin yüzlerce kod satırı içerdiğini düşünün.
function Test-MrVerboseOutput {
[CmdletBinding()]
param (
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = $env:COMPUTERNAME
)
foreach ($Computer in $ComputerName) {
#Attempting to perform an action on $Computer <<-- Don't use
#inline comments like this, use write verbose instead.
Write-Output $Computer
}
}
Satır içi açıklamalar yerine Write-Verbose
kullanmak daha iyi bir seçenektir.
function Test-MrVerboseOutput {
[CmdletBinding()]
param (
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = $env:COMPUTERNAME
)
foreach ($Computer in $ComputerName) {
Write-Verbose -Message "Attempting to perform an action on $Computer"
Write-Output $Computer
}
}
İşlev Ayrıntılı parametresi olmadan çağrıldığında ayrıntılı çıkış görüntülenmez.
Test-MrVerboseOutput -ComputerName Server01, Server02
İşlev Ayrıntılı parametresiyle çağrıldığında ayrıntılı çıkış görüntülenir.
Test-MrVerboseOutput -ComputerName Server01, Server02 -Verbose
İşlem hattı girişi
İşlevinizin işlem hattı girişini kabul etmelerini istediğinizde ek kod gereklidir. Bu kitapta daha önce belirtildiği gibi, komutlar değer (türe göre) ya da özellik adındanişlem hattı girişini
Belirli bir parametre içindeğerine göre işlem hattı girdisi
İşlem hattı girdisi, öğelerin bir foreach
döngüsünde işlenmesine benzer şekilde, tek seferde bir öğe alır.
İşleviniz giriş olarak bir dizi kabul ederse her öğeyi işlemek için bir process
bloğu gerekir. İşleviniz yalnızca tek bir değeri giriş olarak kabul ederse, process
bloğu gerekli değildir, ancak tutarlılık için önerilir.
function Test-MrPipelineInput {
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipeline)]
[string[]]$ComputerName
)
process {
Write-Output $ComputerName
}
}
Özellik adına göre işlem hattı girişi kabul etmek benzerdir; ancak, parametre özniteliği ile belirtirsiniz ve bu, veri türüne bakılmaksızın herhangi bir sayıda parametre için belirtilebilir. Önemli olan, içeri aktarılmakta olan komutun çıkışının, işlevinizin parametre adı veya parametre diğer adıyla eşleşen bir özellik adına sahip olmasıdır.
function Test-MrPipelineInput {
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipelineByPropertyName)]
[string[]]$ComputerName
)
process {
Write-Output $ComputerName
}
}
begin
ve end
blokları isteğe bağlıdır.
begin
process
bloğundan önce belirtilir ve öğeler işlem hattından alınmadan önce herhangi bir ilk işi gerçekleştirmek için kullanılır. Aktarılmış değerlere begin
bloğundan erişilemez.
end
bloğu, process
bloğundan sonra belirtilir ve tüm kanallanan öğeler işlendiğinde temizlik amacıyla kullanılır.
Hata işleme
Aşağıdaki örnekte gösterilen işlev, bir bilgisayarla bağlantı kurulamıyorsa işlenmeyen bir özel durum oluşturur.
function Test-MrErrorHandling {
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]$ComputerName
)
process {
foreach ($Computer in $ComputerName) {
Test-WSMan -ComputerName $Computer
}
}
}
PowerShell'deki hataları işlemenin birkaç farklı yolu vardır.
Try/Catch
, hataları işlemenin daha modern bir yoludur.
function Test-MrErrorHandling {
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]$ComputerName
)
process {
foreach ($Computer in $ComputerName) {
try {
Test-WSMan -ComputerName $Computer
}
catch {
Write-Warning -Message "Unable to connect to Computer: $Computer"
}
}
}
}
Önceki örnekte gösterilen işlev hata işlemeyi kullansa da, komut sonlandırıcı bir hata oluşturmadığından işlenmeyen bir özel durum oluşturur. Yalnızca sonlandırıcı hatalar yakalanır. ErrorAction parametresinin değerini Stop olarak belirterek sonlandırılmayan bir hatayı sonlandırıcı hataya dönüştürün.
function Test-MrErrorHandling {
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]$ComputerName
)
process {
foreach ($Computer in $ComputerName) {
try {
Test-WSMan -ComputerName $Computer -ErrorAction Stop
}
catch {
Write-Warning -Message "Unable to connect to Computer: $Computer"
}
}
}
}
Kesinlikle gerekli olmadıkça genel $ErrorActionPreference
değişkenini değiştirmeyin. Yerel kapsamda değiştirirseniz, bu kapsamdan çıktığınızda önceki değere geri döner.
Doğrudan PowerShell işlevinizin içinden .NET gibi bir şey kullanıyorsanız, komutun kendisinde ErrorAction $ErrorActionPreference
değişkenini değiştirebilirsiniz.
Açıklama tabanlı yardım
İşlevlerinize yardım eklemek en iyi uygulama olarak kabul edilir. Yardım, paylaştığınız kişilerin bunları nasıl kullanacaklarını bilmelerini sağlar.
function Get-MrAutoStoppedService {
<#
.SYNOPSIS
Returns a list of services that are set to start automatically, are not
currently running, excluding the services that are set to delayed start.
.DESCRIPTION
Get-MrAutoStoppedService is a function that returns a list of services
from the specified remote computer(s) that are set to start
automatically, are not currently running, and it excludes the services
that are set to start automatically with a delayed startup.
.PARAMETER ComputerName
The remote computer(s) to check the status of the services on.
.PARAMETER Credential
Specifies a user account that has permission to perform this action. The
default is the current user.
.EXAMPLE
Get-MrAutoStoppedService -ComputerName 'Server1', 'Server2'
.EXAMPLE
'Server1', 'Server2' | Get-MrAutoStoppedService
.EXAMPLE
Get-MrAutoStoppedService -ComputerName 'Server1' -Credential (Get-Credential)
.INPUTS
String
.OUTPUTS
PSCustomObject
.NOTES
Author: Mike F. Robbins
Website: https://mikefrobbins.com
Twitter: @mikefrobbins
#>
[CmdletBinding()]
param (
)
#Function Body
}
İşlevlerinize açıklama tabanlı yardım eklediğinizde, varsayılan yerleşik komutlar gibi bunlar için yardım alınabilir.
PowerShell'de işlev yazmak için kullanılan tüm söz dizimi, çalışmaya başlayan biri için çok zor görünebilir. Bir şeyin söz dizimini anımsayamıyorsanız, ayrı bir monitörde PowerShell Tümleşik Betik Ortamı'nın (ISE) ikinci bir örneğini açın ve işlevlerinizin kodunu yazarken "Cmdlet (gelişmiş işlev) - Complete" kod parçacığını görüntüleyin. Kod parçacıklarına PowerShell ISE'de Ctrl + J tuş bileşimi kullanılarak erişilebilir.
Özet
Bu bölümde, PowerShell'de aşağıdakiler de dahil olmak üzere işlev yazmanın temellerini öğrendiniz:
- Gelişmiş işlevler oluşturma
- Parametre doğrulamayı kullanma
- Ayrıntılı çıktı kullan
- işlem hattı girdisini destekle
- Hataları yönet
- Açıklama tabanlı yardım oluşturma
Eleştiri
- PowerShell'de onaylanan fiillerin listesini nasıl elde edebilirsiniz?
- PowerShell işlevini gelişmiş bir işleve nasıl dönüştürebilirsiniz?
- PowerShell işlevlerinize WhatIf ve Confirm parametreleri ne zaman eklenmelidir?
- Bitmeyen bir hatayı sonlanan bir hataya nasıl dönüştürebilirsiniz?
- İşlevlerinize neden açıklama tabanlı yardım eklemelisiniz?
Kaynaklar
PowerShell