[玩转系统] 度量元 PowerShell 脚本
作者:精品下载站 日期:2024-12-14 08:06:30 浏览:13 分类:玩电脑
度量元 PowerShell 脚本
前几天我正在摆弄 PowerShell。我每天都在 PowerShell 提示符前度过,并且总是寻找解决问题或回答问题的方法,而无需将手从键盘上移开。出于某种原因,我开始考虑公制转换。 50 米是多少英尺? 21.5 英尺是多少米?对于这种事情,我有一个大概的想法。但不是像将克转换为盎司那样。但我可以查找公式并使用 PowerShell。
$v = 123.456
$v/28.35
此代码段会将克 ($v) 的值转换为盎司。看起来很简单。我什至可以围绕它构建一个函数。
Function Convert-Gram {
[cmdletbinding()]
[alias("gr2oz")]
[outputType([System.Double])]
Param(
[Parameter(Position = 0, HelpMessage = "Specify a gram value.")]
[double]$Value,
[Parameter(HelpMessage = "Round the result to this many decimal places")]
[int]$Round = 2
)
$from = "grams"
$to = "ounces"
Write-Verbose "Converting $value $from to $to"
[math]::Round($value / 28.35, $round)
{
事实上,我花时间手动创建了从一种单位转换为另一种单位所需的所有函数。
Function Convert-Millimeter {
[cmdletbinding()]
[alias("mm2in")]
[OutputType([System.Double])]
Param(
[Parameter(Position = 0, HelpMessage = "Specify a millimeter value.")]
[double]$Value,
[Parameter(HelpMessage = "Round the result to this many decimal places")]
[int]$Round = 2
)
$from = "millimeters"
$to = "inches"
Write-Verbose "Converting $value $from to $to"
[math]::Round($value/25.4, $round)
}
当我完成后,我意识到我花了很多时间手动编写脚本。我本可以做的就是让 PowerShell 为我编写函数!
元脚本
我决定看看是否可以编写 PowerShell 代码来编写 PowerShell 代码。首先,我需要一些指导方针。首先,我想要的只是 PowerShell 会话中存在的函数。我不需要文件。我想遵循使用 Convert 动词的标准命名约定。我希望每个命令都有一个简短的别名,以便更容易从控制台使用。
我的元函数需要接受来自单元的参数,例如克,以及至单位,例如盎司。这应该生成一个名为 Convert-GramToOunce 的函数,其别名为 gr2oz。新函数名称的构造非常简单。
$name = "global:Convert-$($from)To$($To)"
您会注意到我使用了 global: 前缀。这是因为,最终我将在 Function: PSDrive 中创建该函数。
New-Item -Path function: -Name $name -Value $value -Force
但由于作用域的原因,当它在元函数中运行时,它不会在我期望的全局作用域中创建该函数。 New-Item cmdlet 没有像某些 cmdlet(即 New-PSDrive)那样的 -Scope 参数。相反,我必须依靠 global: 前缀来给 PowerShell 提示。
该函数的值将是从此处字符串构建的脚本块。
$value = [scriptblock]::Create($body)
这里的字符串最初是我原始函数体的副本。
$body = @"
$help
[Cmdletbinding()]
[Alias("$alias")]
[OutputType([System.Double])]
Param(
[Parameter(Position = 0, Mandatory,ValueFromPipeline,HelpMessage = "Specify a $($from.tolower()) value.")]
[ValidateNotNullOrEmpty()]
$(If ($Validation) {
$v = "[$validation]"
$v
})
[double]`$Value,
[Parameter(HelpMessage = "Round the result to this many decimal places. Specify a value between 0 and 10.")]
[ValidateRange(0,10)]
[int]`$Round = 2,
[Parameter(HelpMessage = "Get a rich object result.")]
[switch]`$Detailed
)
Process {
Write-Verbose "Converting `$value from $($from.tolower()) to $($to.ToLower()) rounded to `$round decimal places."
`$r = [math]::Round(($code),`$round)
if (`$Detailed) {
[PSCustomObject]@{
$From = `$Value
$To = `$r
}
}
else {
`$r
}
}
"@
$code 和 $from 等变量将从参数值扩展。但我必须小心转义像Detailed 这样的变量。我希望最终的代码使用函数中的 $Detailed 。不要用我的元函数中的值替换它。
我应该指出,即使该函数包含 Alias 定义,创建函数项也不会处理该指令。我需要在元函数中手动定义别名。
Set-Alias -Name $alias -Value $name -Scope Global
请注意 Scope 参数的使用。我从名称哈希表构建别名。
$abbreviations = @{
gram = "gr"
ounce = "oz"
meter = "m"
feet = "ft"
millimeter = "mm"
inch = "in"
mile = "mi"
kilometer = "km"
kilogram = "kg"
pound = "lb"
fahrenheit = "f"
celsius = "c"
yard = "yd"
liter = "l"
quart = "qt"
milliliter = "ml"
kelvin = "k"
}
$alias = "{0}2{1}" -f $abbreviations[$from], $abbreviations[$to]
这就是我创建 gr2oz 别名的方法。
我的元函数采用一个字符串作为转换代码。这是我在原始公制转换函数中使用的算法。
添加帮助
我还决定自动生成基于评论的帮助。我正在基于模板动态创建函数。生成帮助应该没有什么不同。我可以创建一个此处字符串并放入参数值。我为此任务编写了一个单独的函数。
Function New-MetricFunctionHelp {
[cmdletbinding()]
Param (
[Parameter(ValueFromPipelineByPropertyName)]
[string]$From,
[Parameter(ValueFromPipelineByPropertyName)]
[string]$To,
[string]$Alias,
[double]$ExampleValue
)
$cmd = "Convert-$($From)To$($To)"
#create the example value object
$obj = [pscustomobject] @{
$From = 1
$To = $ExampleValue
} | Out-String
$h = @"
<#
.Synopsis
Convert a value from $From to $To.
.Description
Use this function to convert values between $from and $to. The default output
is the converted value. Or you can use -Detailed to get a rich object. See examples.
.Parameter Value
Specify a value for the $($from.tolower()) unit.
.Parameter Round
Round the result to this many decimal places. Specify a value between 0 and 10.
.Parameter Detailed
Get a rich object result.
.Example
PS C:\> $cmd 1
$ExampleValue
Get a value result.
.Example
PS C:\> $cmd 1 -detailed
$($obj.trim())
Get an object result.
.Example
PS C:\> $alias 1
$ExampleValue
Using the function alias.
.Link
Convert-$($To)To$($From)
.Notes
This command has an alias of $alias. This is an auto-generated function.
.Inputs
System.Double
.Outputs
System.Double
#>
"@
$h
}
该函数在 New-MetricFunction 中调用。因为我需要样本的实际值,所以我生成一个值并将其传递给帮助函数。
$b = [scriptblock]::create("param (`$value) [math]::Round($code,2)")
$v1 = Invoke-Command $b -ArgumentList 1
$help = New-MetricFunctionHelp -From $From -to $To -Alias $alias -ExampleValue $v1
重新运行我的命令来创建 Convert-GramToOunce 会生成此代码。
<#
.Synopsis
Convert a value from Gram to Ounce.
.Description
Use this function to convert values between Gram and Ounce. The default output
is the converted value. Or you can use -Detailed to get a rich object. See examples.
.Parameter Value
Specify a value for the gram unit.
.Parameter Round
Round the result to this many decimal places. Specify a value between 0 and 10.
.Parameter Detailed
Get a rich object result.
.Example
PS C:\> Convert-GramToOunce 1
0.04
Get a value result.
.Example
PS C:\> Convert-GramToOunce 1 -detailed
Gram Ounce
---- -----
1 0.04
Get an object result.
.Example
PS C:\> gr2oz 1
0.04
Using the function alias.
.Link
Convert-OunceToGram
.Notes
This command has an alias of gr2oz. This is an auto-generated function.
.Inputs
System.Double
.Outputs
System.Double
#>
[Cmdletbinding()]
[Alias("gr2oz")]
[OutputType([System.Double])]
Param(
[Parameter(Position = 0, Mandatory,ValueFromPipeline,HelpMessage = "Specify a gram value.")]
[ValidateNotNullOrEmpty()]
[double]$Value,
[Parameter(HelpMessage = "Round the result to this many decimal places. Specify a value between 0 and 10.")]
[ValidateRange(0,10)]
[int]$Round = 2,
[Parameter(HelpMessage = "Get a rich object result.")]
[switch]$Detailed
)
Process {
Write-Verbose "Converting $value from gram to ounce rounded to $round decimal places."
$r = [math]::Round(($value/28.35),$round)
if ($Detailed) {
[PSCustomObject]@{
Gram = $Value
Ounce = $r
}
}
else {
$r
}
}
从数据生成
还在我这儿?这是完整的元脚本函数。
Function New-MetricFunction {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[string]$From,
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[string]$To,
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[string]$Code,
[Parameter(ValueFromPipelineByPropertyName)]
[string]$Validation
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
#hash table of unit abbreviations used to construct aliases
$abbreviations = @{
gram = "gr"
ounce = "oz"
meter = "m"
feet = "ft"
millimeter = "mm"
inch = "in"
mile = "mi"
kilometer = "km"
kilogram = "kg"
pound = "lb"
fahrenheit = "f"
celsius = "c"
yard = "yd"
liter = "l"
quart = "qt"
milliliter = "ml"
kelvin = "k"
}
} #begin
Process {
#make sure From and To are in proper case
$from = (Get-Culture).TextInfo.ToTitleCase($from.toLower())
$to = (Get-Culture).TextInfo.ToTitleCase($to.toLower())
#define a function name that will be found in the global scope
$name = "global:Convert-$($from)To$($To)"
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Creating function Convert-$($from)To$($To)"
#construct an alias from the data
$alias = "{0}2{1}" -f $abbreviations[$from], $abbreviations[$to]
#build comment-based help
$b = [scriptblock]::create("param (`$value) [math]::Round($code,2)")
$v1 = Invoke-Command $b -ArgumentList 1
$help = New-MetricFunctionHelp -From $From -to $To -Alias $alias -ExampleValue $v1
# this here string will be turned into the function's scriptblock. I need to be careful
# to escape $ where I want it to remain a variable in the output.
$body = @"
$help
[Cmdletbinding()]
[Alias("$alias")]
[OutputType([System.Double])]
Param(
[Parameter(Position = 0, Mandatory,ValueFromPipeline,HelpMessage = "Specify a $($from.tolower()) value.")]
[ValidateNotNullOrEmpty()]
$(If ($Validation) {
$v = "[$validation]"
$v
})
[double]`$Value,
[Parameter(HelpMessage = "Round the result to this many decimal places. Specify a value between 0 and 10.")]
[ValidateRange(0,10)]
[int]`$Round = 2,
[Parameter(HelpMessage = "Get a rich object result.")]
[switch]`$Detailed
)
Process {
Write-Verbose "Converting `$value from $($from.tolower()) to $($to.ToLower()) rounded to `$round decimal places."
`$r = [math]::Round(($code),`$round)
if (`$Detailed) {
[PSCustomObject]@{
$From = `$Value
$To = `$r
}
}
else {
`$r
}
}
"@
$value = [scriptblock]::Create($body)
if ($PSCmdlet.ShouldProcess($name)) {
New-Item -Path function: -Name $name -Value $value -Force
}
if ($PSCmdlet.ShouldProcess($name, "Create alias $alias")) {
#need to manually create the alias even though it is defined in the function
Set-Alias -Name $alias -Value $name -Scope Global
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
}
该函数还允许我为该值指定一个参数验证字符串。另请注意,我将参数配置为按属性名称接受管道输入。
我可以使用外部数据源(例如 CSV 文件)来生成所有函数。在具有先前定义的函数的脚本文件中,我像这样定义 CSV 数据。
#use single quote for the here-string so that $value doesn't get
#treated as a variable upon conversion
$data = @'
From,To,Code,Validation
Gram,Ounce,$value/28.35,ValidateScript({$_ -gt 0})
Ounce,Gram,$value*28.35,ValidateScript({$_ -gt 0})
Millimeter,Inch,$value/25.4,ValidateScript({$_ -gt 0})
Inch,Millimeter,$value*25.4,ValidateScript({$_ -gt 0})
Meter,Feet,$value*3.281,ValidateScript({$_ -gt 0})
Feet,Meter,$value/3.281,ValidateScript({$_ -gt 0})
Kilometer,Mile,$value/1.609,ValidateScript({$_ -gt 0})
Mile,Kilometer,$value*1.609,ValidateScript({$_ -gt 0})
Kilogram,Pound,$value*2.205,ValidateScript({$_ -gt 0})
Pound,Kilogram,$value/2.205,ValidateScript({$_ -gt 0})
Yard,Meter,$value/1.094,ValidateScript({$_ -gt 0})
Meter,Yard,$value*1.094,ValidateScript({$_ -gt 0})
Liter,Quart,$value*1.057,ValidateScript({$_ -gt 0})
Quart,Liter,$value/1.057,ValidateScript({$_ -gt 0})
Milliliter,Ounce,$value/29.574,ValidateScript({$_ -gt 0})
Ounce,Milliliter,$value*29.574,ValidateScript({$_ -gt 0})
Celsius,Fahrenheit,($value*(9/5)) + 32
Fahrenheit,Celsius,($value - 32)*(5/9)
Kelvin,Fahrenheit,($value-273.15)*(9/5)+32
Fahrenheit,Kelvin,($value-32)*(5/9)+273.15
Kelvin,Celsius,($value - 273.15)
Celsius,Kelvin,($value + 273.15)
'@
导入此数据并将其传递给元脚本函数是一个单行命令。
$new = $data | ConvertFrom-Csv | New-MetricFunction
最后,为了让我更容易记住所有新命令,我将创建一个“备忘单”。
$metric = $new | Select-Object -Property Name, @{Name = "Alias"; Expression = { Get-Alias -Definition "global:$($_.name)" } }
$metric
假设我对 PowerShell 脚本文件进行点源,我将有一个引用变量。
通过一个命令,我创建了所有这些函数并将它们加载到我的 PowerShell 会话中。
如果我决定更改某些内容(例如详细消息),我可以修改 New-MetricFunction 并重新生成函数。我不必在 22 个不同的文件中进行更改。
概括
虽然我重视结果并将使用这些度量转换函数,但我的真正目的是共享元脚本内容和技术。我心里没有其他项目要使用它,但当我这样做时我会做好更好的准备。如果您找到使用这些技术的方法,我希望您能分享。
- 上一篇:[玩转系统] 管理原始目录搜索者数据
- 下一篇:[玩转系统] 我没有告诉你!
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag