Chuyển đổi tập lệnh PowerShell thành hàm
Gần đây, tôi đã chia sẻ một số mã PowerShell để xuất một hàm thành một tệp. Đó là một bài viết phổ biến. Bạn tôi Richard Hicks (không có quan hệ) nghĩ rằng chúng tôi đang nói đùa khi anh ấy hỏi về việc chuyển đổi tập tin thành hàm. Ý tưởng của anh là lấy một loạt tập lệnh PowerShell, biến chúng thành một nhóm chức năng mà sau đó có thể tổ chức thành một mô-đun. Đây không phải là điều quá xa vời. Vì vậy, tôi đã dành chút thời gian trong vài ngày qua và nghĩ ra hàm PowerShell để lấy tệp tập lệnh PowerShell hiện có và biến nó thành hàm PowerShell.
Thực tế mà nói, không có sự khác biệt giữa việc chạy mã bên trong hàm và tập lệnh. Về cốt lõi, một hàm là một khối tập lệnh có tên giúp dễ chạy hơn. Mã bên trong scriptblock không khác gì mã bạn có thể có trong một tập lệnh độc lập. Tùy thuộc vào tập lệnh của bạn, bạn có thể chỉ cần gói mã tập lệnh của mình trong phần khai báo Hàm. Tất nhiên, cách tốt nhất là để các hàm thực hiện một tác vụ duy nhất và ghi một loại đối tượng duy nhất vào quy trình, do đó bạn vẫn có thể cần chỉnh sửa hàm kết quả của mình. Điều tôi nghĩ ra là một công cụ PowerShell sử dụng AST để đẩy nhanh quá trình.
Ví dụ cơ bản
Đây là một tập lệnh PowerShell cực kỳ đơn giản.
#requires -version 3.0
#this is a sample script
Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow
Get-Random -Minimum 1 -Maximum 1000Tôi muốn biến chức năng này thành chức năng PowerShell nên tôi sẽ sử dụng công cụ mới của mình.
Lệnh Convert-ScriptToFunction của tôi rõ ràng cần đường dẫn đến tệp. Tôi cũng cần chỉ định tên cho hàm mới. Việc chuyển đổi tạo ra một định nghĩa hàm mới hoàn chỉnh với sự trợ giúp dựa trên nhận xét. Tập lệnh gốc không có các tham số được xác định nên quá trình chuyển đổi đã xác định chúng. Nếu tôi muốn lưu tệp này vào một tệp, tất cả những gì tôi cần làm là chạy lệnh và chuyển sang Tệp ngoài. Sau đó tôi có thể mở tệp trong trình soạn thảo tập lệnh của mình để đánh bóng nó.
Nhận yêu cầu
Bạn sẽ nhận thấy rằng mã mới bao gồm các câu lệnh #requires từ tệp gốc. Tôi đã viết một hàm riêng, đồng thời sử dụng AST để đáp ứng bất kỳ yêu cầu nào. Trong tập lệnh New-SystemReport.ps1 của tôi, tôi có những yêu cầu này.
#requires -version 5.1
#requires -module CimCmdletsTôi có thể sử dụng chức năng này để khám phá chúng.
Function Get-PSRequirements {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]$Path
)
Begin {
Write-Verbose "Starting $($MyInvocation.MyCommand)"
New-Variable astTokens -Force
New-Variable astErr -Force
}
Process {
$Path = Convert-Path $path
Write-Verbose "Processing $path"
$AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)
#add the Path as a property
if ($ast.ScriptRequirements) {
$ast.ScriptRequirements | Add-Member -MemberType NoteProperty -Name "Path" -Value $Path-Force -PassThru
}
else {
Write-Verbose "No requirements detected in $Path."
}
}
End {
Write-Verbose "Ending $($MyInvocation.MyCommand)"
}
}Trợ giúp dựa trên nhận xét
Tôi cũng muốn có thể tạo trợ giúp dựa trên nhận xét nếu nó chưa được xác định. Sử dụng AST ParamBlock tôi tạo một khối như vậy. Tôi luôn yêu cầu mọi người sử dụng thuộc tính HelpMessage và nếu bạn làm vậy, nó sẽ được sử dụng cho định nghĩa .Parameter.
Function New-CommentHelp {
[cmdletbinding()]
[OutputType("string")]
Param([System.Management.Automation.Language.ParamBlockAst]$ParamBlock)
$h = [System.Collections.Generic.List[string]]::new()
$h.Add("<#")
$h.Add("`t.Synopsis")
$h.Add("`t <short description>")
$h.add("`t.Description")
$h.add("`t <long description>")
foreach ($p in $ParamBlock.Parameters) {
$paramName = $p.name.variablepath.userpath
$h.Add("`t.Parameter $paramName")
$paramHelp = $p.Attributes.namedArguments.where({ $_.argumentname -eq 'helpmessage' })
if ($paramHelp) {
$h.add("`t $($paramHelp.argument.value)")
}
else {
$h.Add("`t <enter a parameter description>")
}
}
$h.add("`t.Example")
$h.Add("`t PS C:\> $Name")
$h.Add("`t <output and explanation>")
$h.Add("`t.Link")
$h.Add("`t <enter a link reference>")
$h.Add("#>")
$h
}
Đây là một kịch bản mẫu.
#requires -version 3.0
#this is a sample script
Param (
[Parameter(Position = 0,HelpMessage = "How many numbers do you want?")]
[int]$Count = 1,
[string]$Name,
[switch]$Demo
)
Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow
#get numbers
1..$count | Foreach-Object {
Get-Random -Minimum 1 -Maximum 1000
}
Write-Host "Ending script" -ForegroundColor yellow
#eofSử dụng chức năng chuyển đổi của tôi, tôi nhận được kết quả này.
#requires -version 3.0
# Function exported from C:\scripts\SampleScript3.ps1
Function Invoke-Sample {
<#
.Synopsis
<short description>
.Description
<long description>
.Parameter Count
How many numbers do you want?
.Parameter Name
<enter a parameter description>
.Parameter Demo
<enter a parameter description>
.Example
PS C:\> Invoke-Sample
<output and explanation>
.Link
<enter a link reference>
#>
[cmdletbinding()]
Param (
[Parameter(Position = 0,HelpMessage = "How many numbers do you want?")]
[int]$Count = 1,
[string]$Name,
[switch]$Demo
)
Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow
1..$count | Foreach-Object {
Get-Random -Minimum 1 -Maximum 1000
}
Write-Host "Ending script" -ForegroundColor yellow
} #close Invoke-SampleTên chức năng
Vì tôi phải xác định tên hàm mới nên tôi muốn tên này càng đơn giản càng tốt. Tôi sử dụng chức năng trợ giúp này để định dạng tên theo kiểu chữ thích hợp. Tôi đang giả định quy ước đặt tên Động từ-Danh từ.
Function Format-FunctionName {
[cmdletbinding()]
Param (
[ValidateScript({
if ($_ -match "^\w+-\w+$") {
$true
}
else {
Throw "Your function name should have a Verb-Noun naming convention"
$False
}
})]
[string]$Name
)
$split = $name -split "-"
"{0}{1}-{2}{3}" -f $split[0][0].ToString().ToUpper(), $split[0].Substring(1).Tolower(),$split[1][0].ToString().ToUpper(), $split[1].Substring(1).ToLower()
}Nó không phải lúc nào cũng hoàn hảo, đặc biệt nếu danh từ của bạn phức tạp như ví dụ này. Hàm này cũng không xác thực rằng bạn đang sử dụng động từ chuẩn. Tuy nhiên, tôi có một trình hoàn thành đối số sẽ chèn một động từ tiêu chuẩn.
Register-ArgumentCompleter -CommandName Convert-ScriptToFunction -ParameterName Name -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
#PowerShell code to populate $wordtoComplete
Get-Verb | Where-Object {$_.verb -match "^$wordToComplete"} |
ForEach-Object {
#this will autocomplete with Verb-
[System.Management.Automation.CompletionResult]::new("$($_.verb)-", $_.verb, 'ParameterValue', $_.Group)
}
}
Tất cả những gì tôi cần làm là bắt đầu nhập tên động từ và nhấn Tab. Việc hoàn thành sẽ chèn động từ và dấu gạch ngang. Tất cả những gì tôi cần gõ là danh từ.
Làm việc với đầu ra
Chức năng của tôi thực hiện chính xác những gì nó nói. Nó chuyển đổi. Bạn có quyền quyết định cách bạn muốn sử dụng đầu ra. Bạn có thể chuyển sang Out-File hoặc Set-Clipboard. Nhưng vì tôi cho rằng bạn sẽ chỉnh sửa ngay kết quả đầu ra của mình nên tôi đã thêm một tham số động (sử dụng hàm New-PSDynamicParameterForm) có tên là ToEditor. Tham số này sẽ được xác định nếu bạn chạy hàm trong Mã PowerShell ISE hoặc VS. Đầu ra sẽ được mở trong một tệp mới, chưa được lưu.
Một lần nữa, đây là tập tin nguồn. Đây là những tập lệnh tôi tạo chỉ để kiểm tra chức năng của mình.
#requires -version 4.0
#requires -runasAdministrator
#this is a sample script
Param (
[Parameter(Position = 0,HelpMessage = "How many numbers do you want?")]
[ValidateRange(1,100)]
[int]$Count = 1
)
DynamicParam {
#this is a sample dynamic parameter
If ($True) {
$paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
# Defining parameter attributes
$attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributes = New-Object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = '__AllParameterSets'
$attributeCollection.Add($attributes)
# Defining the runtime parameter
$dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('Demo', [String], $attributeCollection)
$paramDictionary.Add('Demo', $dynParam1)
return $paramDictionary
} # end if
} #end DynamicParam
Begin {
Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow
}
Process {
#get numbers
1..$count | Foreach-Object {
Get-Random -Minimum 1 -Maximum 1000
}
}
End {
write-host "Ending script" -ForegroundColor yellow
}
#eofTôi sẽ chạy mã này trong thiết bị đầu cuối PowerShell tích hợp trong Mã VS để tạo tệp mới. Hàm này cũng sẽ có bí danh mới.
Convert-ScriptToFunction .\SampleScript4.ps1 -Name Invoke-Sample -Alias ins -ToEditorSau đó tôi có thể sử dụng VSCode để dọn dẹp tệp như định dạng, mở rộng bí danh và chuyển đổi tab thành dấu cách. Sau đó tôi có thể lưu tập tin. Đầu ra bao gồm một tham chiếu đến tệp nguồn gốc.
Chuyển đổi-ScriptToFunction
Đây là chức năng chuyển đổi.
Function Convert-ScriptToFunction {
<#
.Synopsis
Convert a script file to a PowerShell function.
.Description
This command takes the body of a script file and wraps it in a function
declaration. The command will insert missing elements like [cmdletbinding()]
and comment-based help. You will most likely need to edit and clean up the
result in your scripting editor.
If you run this command in the PowerShell ISE or the VS Code PowerShell
integrated terminal, you can use the dynamic parameter ToEditor to open a
new file with with the output. You can edit and save the file manually.
It is assumed that your script file is complete and without syntax errors.
.Parameter Path
Enter the path to your PowerShell script file.
.Parameter Name
What is the name of your new function? It should have a Verb-Noun name.
.Parameter Alias
Define an optional alias for your new function.
.Parameter ToEditor
If you run this command in the PowerShell ISE or the VS Code PowerShell
integrated terminal, you can use this dynamic parameter to open a new
file with with the output. You can edit and save the file manually.
.Example
PS C:\> Convert-ScriptToFunction c:\scripts\Daily.ps1 -name Invoke-DailyTask | Set-Clipboard
Convert Daily.ps1 to a function called Invoke-DailyTask and copy the
results to the Windows clipboard. You can then paste the results into
scripting editor.
.Example
PS C:\> Convert-ScriptToFunction c:\scripts\systemreport.ps1 -name New-SystemReport | Out-File c:\scripts\New-SystemReport.ps1
Convert the SystemReport.ps1 script file to a function called
New-SystemReport and save the results to a file.
.Example
PS C:\> Convert-ScriptToFunction c:\scripts\systemreport.ps1 -name New-System -alias nsr | Tee-Object -variable f
Convert the script to a function called New-System and tee the output to $f.
This will also define an function alias of nsr.
#>
[cmdletbinding()]
[Outputtype("System.String")]
[alias('csf')]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipelineByPropertyName,
HelpMessage = "Enter the path to your PowerShell script file."
)]
[ValidateScript({Test-Path $_ })]
[ValidatePattern("\.ps1$")]
[string]$Path,
[Parameter(
Position = 1,
Mandatory,
ValueFromPipelineByPropertyName,
HelpMessage = "What is the name of your new function?")]
[ValidateScript({
if ($_ -match "^\w+-\w+$") {
$true
}
else {
Throw "Your function name should have a Verb-Noun naming convention"
$False
}
})]
[string]$Name,
[Parameter(ValueFromPipelineByPropertyName,HelpMessage = "Specify an optional alias for your new function. You can define multiple aliases separated by commas.")]
[ValidateNotNullOrEmpty()]
[string[]]$Alias
)
DynamicParam {
<#
If running this function in the PowerShell ISE or VS Code,
define a ToEditor switch parameter
#>
If ($host.name -match "ISE|Code") {
$paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
# Defining parameter attributes
$attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributes = New-Object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = '__AllParameterSets'
$attributeCollection.Add($attributes)
# Defining the runtime parameter
$dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('ToEditor', [Switch], $attributeCollection)
$paramDictionary.Add('ToEditor', $dynParam1)
return $paramDictionary
} # end if
} #end DynamicParam
Begin {
Write-Verbose "Starting $($MyInvocation.MyCommand)"
Write-Verbose "Initializing"
New-Variable astTokens -Force
New-Variable astErr -Force
$new = [System.Collections.Generic.list[string]]::new()
} #begin
Process {
#normalize
$Path = Convert-Path $path
$Name = Format-FunctionName $Name
Write-Verbose "Processing $path"
$AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)
if ($ast.extent) {
Write-Verbose "Getting any comment based help"
$ch = $astTokens | Where-Object { $_.kind -eq 'comment' -AND $_.text -match '\.synopsis' }
if ($ast.ScriptRequirements) {
Write-Verbose "Adding script requirements"
if($ast.ScriptRequirements.RequiredPSVersion) {
$new.Add("#requires -version $($ast.ScriptRequirements.RequiredPSVersion.ToString())")
}
if ($ast.ScriptRequirements.RequiredModules) {
Foreach ($m in $ast.ScriptRequirements.RequiredModules) {
#test for version requirements
$ver = $m.psobject.properties.where({$_.name -match 'version' -AND $_.value})
if ($ver) {
$new.Add("#requires -module @{ModuleName = '$($m.name)';$($ver.Name) = '$($ver.value)'}")
}
else {
$new.add("#requires -module $($m.Name)")
}
}
}
if ($ast.ScriptRequirements.IsElevationRequired) {
$new.Add("#requires -RunAsAdministrator")
}
If ($ast.ScriptRequirements.requiredPSEditions) {
$new.add("#requires -PSEdition $($ast.ScriptRequirements.requiredPSEditions)")
}
$new.Add("`n")
}
else {
Write-Verbose "No script requirements found"
}
$head = @"
# Function exported from $Path
Function $Name {
"@
$new.add($head)
if ($ch) {
$new.Add($ch.text)
$new.Add("`n")
}
else {
Write-Verbose "Generating new comment based help from parameters"
New-CommentHelp -ParamBlock $ast.ParamBlock | Foreach-Object { $new.Add("$_")}
$new.Add("`n")
}
[regex]$rx = "\[cmdletbinding\(.*\)\]"
if ($rx.Ismatch($ast.Extent.text)) {
Write-Verbose "Using existing cmdletbinding"
#use the first match
$cb = $rx.match($ast.extent.text).Value
$new.Add("`t$cb")
}
else {
Write-Verbose "Adding [cmdletbinding()]"
$new.Add("`t[cmdletbinding()]")
}
if ($alias) {
Write-Verbose "Adding function alias definition $($alias -join ',')"
$new.Add("`t[Alias('$($alias -join "','")')]")
}
if ($ast.ParamBlock) {
Write-Verbose "Adding defined Param() block"
[void]($ast.ParamBlock.tostring().split("`n").Foreach({$new.add("`t$_")}) -join "`n")
$new.Add("`n")
}
else {
Write-Verbose "Adding Param() block"
$new.add("`tParam()")
}
if ($ast.DynamicParamBlock) {
#assumes no more than 1 dynamic parameter
Write-Verbose "Adding dynamic parameters"
[void]($ast.DynamicParamBlock.tostring().split("`n").Foreach({$new.Add($_)}) -join "`n")
}
if ($ast.BeginBlock.Extent.text) {
Write-Verbose "Adding defined Begin block"
[void]($ast.BeginBlock.Extent.toString().split("`n").Foreach({$new.Add($_)}) -join "`n")
$UseBPE = $True
}
if ($ast.ProcessBlock.Extent.text) {
Write-Verbose "Adding defined Process block"
[void]($ast.ProcessBlock.Extent.ToString().split("`n").Foreach({$new.add($_) }) -join "`n")
}
if ($ast.EndBlock.Extent.text) {
if ($UseBPE) {
Write-Verbose "Adding opening End{} block"
$new.Add("`tEnd {")
}
Write-Verbose "Adding the remaining code or defined endblock"
[void]($ast.Endblock.Statements.foreach({ $_.tostring() }).Foreach({ $new.Add($_)}))
if ($UseBPE) {
Write-Verbose "Adding closing End {} block"
$new.Add("`t}")
}
}
else {
$new.Add("End { }")
}
Write-Verbose "Closing the function"
$new.Add( "`n} #close $name")
if ($PSBoundParameters.ContainsKey("ToEditor")) {
Write-Verbose "Opening result in editor"
if ($host.name -match "ISE") {
$newfile = $psise.CurrentPowerShellTab.Files.add()
$newfile.Editor.InsertText(($new -join "`n"))
$newfile.editor.select(1,1,1,1)
}
elseif ($host.name -match "Code") {
$pseditor.Workspace.NewFile()
$ctx = $pseditor.GetEditorContext()
$ctx.CurrentFile.InsertText($new -join "`n")
}
else {
$new -join "`n" | Set-Clipboard
Write-Warning "Can't detect the PowerShell ISE or VS Code. Output has been copied to the clipboard."
}
}
else {
Write-Verbose "Writing output [$($new.count) lines] to the pipeline"
$new -join "`n"
}
} #if ast found
else {
Write-Warning "Failed to find a script body to convert to a function."
}
} #process
End {
Write-Verbose "Ending $($MyInvocation.mycommand)"
}
}Hàm này giả định tệp tập lệnh của bạn đã hoàn chỉnh về mặt cú pháp và không có lỗi. Hãy hiểu rằng không phải mọi tệp tập lệnh đều có thể được chuyển đổi thành hàm PowerShell mà bạn có thể sử dụng ngay. Chức năng chuyển đổi đang nỗ lực hết sức có thể. Bạn nên xem đây như một công cụ để đẩy nhanh công việc viết kịch bản của mình. Tôi cho rằng tôi sẽ cần chỉnh sửa tập tin mới. Nhưng đây là một khởi đầu tốt.
Tôi có thể lấy tập lệnh PowerShell cũ như thế này:
#requires -version 3.0
#Basic-HotFixReport.ps1
Param([string[]]$Computername = $env:COMPUTERNAME)
$ErrorActionPreference = "SilentlyContinue"
Get-Hotfix -ComputerName $Computername |
Select-Object -Property PSComputername,HotFixID,Description,InstalledBy,InstalledOn,
@{Name="Online";Expression={$_.Caption}}
Và tạo một chức năng mới:
csf .\Basic-HotfixReport.ps1 -Name Get-HotFixReport -Alias ghfr | out-file c:\scripts\get-hotfixreport.ps1Hàm của tôi có bí danh là csf. Sau khi chỉnh sửa tập tin để cập nhật nó, tôi có một cái gì đó như thế này.
#requires -version 5.1
# Function exported from C:\scripts\Basic-HotfixReport.ps1
Function Get-HotfixReport {
<#
.Synopsis
Get a hotfix report
.Description
Use this command to get a report of installed hotfixes on a computer.
.Parameter Computername
Enter the name of a computer.
.Example
PS C:\scripts> Get-HotfixReport thinkp1 | format-table
Computername HotFixID Description InstalledBy InstalledOn Online
------------ -------- ----------- ----------- ----------- ------
THINKP1 KB5006363 Update NT AUTHORITY\SYSTEM 11/6/2021 12:00:00 AM http://support.microsoft.com/?kbid=5006363
THINKP1 KB5004567 Update NT AUTHORITY\SYSTEM 7/4/2021 12:00:00 AM https://support.microsoft.com/help/5004567
THINKP1 KB5008295 Update NT AUTHORITY\SYSTEM 11/6/2021 12:00:00 AM https://support.microsoft.com/help/5008295
THINKP1 KB5007262 Update NT AUTHORITY\SYSTEM 11/22/2021 12:00:00 AM https://support.microsoft.com/help/5007262
THINKP1 KB5007414 Update NT AUTHORITY\SYSTEM 11/13/2021 12:00:00 AM
.Link
Get-HotFix
#>
[cmdletbinding()]
[Alias('ghfr')]
Param([string[]]$Computername = $env:COMPUTERNAME)
Try {
Get-HotFix -ComputerName $Computername -ErrorAction Stop |
Select-Object -Property @{Name = "Computername"; Expression = { $_.CSName } },
HotFixID, Description, InstalledBy, InstalledOn,
@{Name = "Online"; Expression = { $_.Caption } }
}
Catch {
Throw $_
}
} #close Get-Hotfixreport
Có lẽ tôi sẽ tiếp tục tinh chỉnh chức năng.
Xây dựng một mô-đun
Tôi sẽ kết thúc điều này bằng một bằng chứng về khái niệm. Giả sử tôi biết các tệp tập lệnh mà tôi muốn sử dụng và tên hàm tôi muốn gán, tôi có thể sử dụng tập lệnh PowerShell để nhanh chóng xây dựng một mô-đun.
#a proof of concept to convert scripts to a new module
#dot source the conversion functions
. C:\scripts\dev-scripttofunction.ps1
$NewModuleName = "PSMagic"
$Description = "A sample module"
$ParentPath = "C:\work"
$path = New-Item -Name $NewModuleName -Path $ParentPath -ItemType Directory -Force
#create the module structure
"docs", "functions", "en-us", "formats" |
ForEach-Object { New-Item -Path $path -Name $_ -ItemType Directory }
#file data
$data = @"
"Path","Name"
"C:\scripts\SampleScript.ps1","Get-Foo"
"C:\scripts\SampleScript2.ps1","Set-Foo"
"C:\scripts\SampleScript3.ps1","Invoke-Foo"
"C:\scripts\SampleScript4.ps1","Remove-Foo"
"C:\scripts\SampleScript5.ps1","Test-Foo"
"@
$csv = $data | ConvertFrom-Csv
foreach ($item in $csv) {
$out = Join-Path $path\functions "$($item.name).ps1"
$item | Convert-ScriptToFunction | Out-File -FilePath $out
Get-Item $out
} #foreach item
#create the root module
$psm1 = @"
Get-Childitem `$psscriptroot\functions\*.ps1 |
Foreach-Object {
. `$_.FullName
}
"@
$psm1 | Out-File "$path\$newmodulename.psm1"
#create the module manifest
$splat = @{
Path = "$path\$newmodulename.psd1"
RootModule = "$path\$newmodulename.psm1"
ModuleVersion = "0.1.0"
Author = "Jeff Hicks"
Description = $Description
FunctionsToExport = $csv.name
PowerShellVersion = "5.1"
CompatiblePSEditions = "Desktop"
}
New-ModuleManifest @splat
Get-ChildItem $pathChạy tập lệnh này sẽ nhanh chóng xây dựng mô-đun của tôi.
Đương nhiên, vẫn sẽ có chỉnh sửa và sửa đổi, nhưng điều này mang lại cho tôi một bước khởi đầu lớn trong quá trình này.
Bước tiếp theo
Tôi hy vọng một số bạn sẽ thử mã này và cho tôi biết suy nghĩ của bạn. Hãy nhớ rằng, nó có thể sẽ không tạo ra các hàm PowerShell hoàn hảo. Tôi nghĩ bây giờ tôi đã có đủ lệnh để có thể gộp tất cả những thứ này lại với nhau thành một mô-đun mới. Trên thực tế, tôi có thể sử dụng chính các công cụ đó để xây dựng mô-đun. Nói về meta!






