[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创教程] PowerShell随机函数微软阿三哥的偷工减料

不知有没有人早发现这个BUG,应该也算是属于BUG了,毕竟自带的函数属于是写错了代码逻辑
  1. Get-Random -Count 3 -Maximum 10
复制代码
同一条代码换到7.3.5版本测试正常输出

但换到比较大众化的版本5.1中这个代码会提示错误,错误如下

发不了截图,直接粘贴错误提示了:

Get-Random : 无法使用指定的命名参数解析参数集。
所在位置 行:1 字符: 1
+ Get-Random -Count 3 -Maximum 10


这个错误的提示其实是因为代码ParameterSetName属性不在对应位置上导致的
  1. function test{
  2.     param(
  3.         [Parameter(ValueFromPipeline,ParameterSetName='A')]
  4.         $a,
  5.         [Parameter(ParameterSetName='B',Position=0)]
  6.         $b
  7.     )
  8. }
  9. test  -a 3 -b 8
复制代码

test : 无法使用指定的命名参数解析参数集。
所在位置 行:11 字符: 1
+ test  -a 3 -b 8

具体是在哪一个新版中修复的就不清楚了

5.1解决方案有很多,一般使用
  1. Get-Random -Count 3 -Maximum 10
复制代码
写法的目的是为了可以控制随机数的小数部分比如
  1. Get-Random -Count 3 -Maximum 10.5
复制代码
解决方案:
  1. $max=100
  2. $count=5
  3. @(for($i=$max*10;$i -lt $max*100;$i+=1){$i/100})|Get-Random -Count $count
复制代码
补充一点:
上面的解决方案在效率上肯定是不如微软自带的函数直接按给定参数来的直接的.

如果你想提高效率或者想解决此问题,有另外两种方式,算比较麻烦的方案了(以下两种方案需要很熟练的知道如何配置PowerShell编程环境才行,请谨慎操作,以免丢失重要数据或模块)
1.下载并安装PowerShell最新版直接将新版的函数copy到旧版中去(如果你懂得如何操作的话)
2.下载安装PowerShell最新版并与旧版共存,想用哪个就用哪个了
1

评分人数

输入 (help get-random)会发现,只有两种语法(5.1版本)
并没有-Count跟-Maximum在一起的语法,当它不存在就是了

TOP

并不是不支持这个语法,是本来就存在,应该有如此使用的方式,但是写错了ParameterSetName属性值,导致count参数丢失

TOP

本帖最后由 Nsqs 于 2023-9-10 03:21 编辑

不要天真的以为help里的说明就是很全

关于PowerShell 7.3版 以上的说明

    Get-Random [[-Maximum] <Object>] [-SetSeed <int>] [-Minimum <Object>] [-Count <int>] [<CommonParameters>]

    Get-Random [-InputObject] <Object[]> [-SetSeed <int>] [-Count <int>] [<CommonParameters>]

    Get-Random [-InputObject] <Object[]> -Shuffle [-SetSeed <int>] [<CommonParameters>]


很显然这个部分的说明中也没有记载可以单独拎出Maximum和Count的方法,包括在官网里的资料也并没有演示他应该有的全部使用方法,仅展示了部分而已

TOP

本帖最后由 Nsqs 于 2023-9-10 03:16 编辑

将下面代码定义好
  1. function rnd{
  2.     param(
  3.         [Parameter(ValueFromPipeline,Position=2,ParameterSetName='A')]
  4.         $InputObject,
  5.         [Parameter(ParameterSetName='B',Position=1)]
  6.         $Min,
  7.         [Parameter(ParameterSetName='B',Position=0)]
  8.         $Max,
  9.         [Parameter(ParameterSetName='A',Position=3)]
  10.         $Count=1
  11.     )   
  12.     if($PSBoundParameters.ContainsKey('InputObject')){
  13.         $input|Get-Random -Count $Count
  14.     }else{        
  15.         Get-Random -Minimum $Min -Maximum $Max
  16.     }
  17. }
复制代码
按如下进行测试
  1. 1,3,5,7|rnd 4
  2. 1,3,5,7|Get-Random 4
  3. rnd -Max 10 -Count 5
  4. Get-Random -Maximum 10 -Count 5
复制代码
效果与原函数如出一辙,就连输入参数不显示count都一样

rnd : 无法将输入对象绑定到命令的任何参数,可能是因为该命令没有采用管道输入,或者输入及其属性与采用管道输入的任何参数均不匹配。

Get-Random : 无法将输入对象绑定到命令的任何参数,可能是因为该命令没有采用管道输入,或者输入及其属性与采用管道输入的任何参数均不匹配。


-------------------------------------------------

rnd : 无法使用指定的命名参数解析参数集。

Get-Random : 无法使用指定的命名参数解析参数集。


-------------------------------------------------

重点测试,发现有个有趣的现象,就连下面这样写报错都一样
  1. 5|rnd 5
复制代码
rnd : 无法将输入对象绑定到命令的任何参数,可能是因为该命令没有采用管道输入,或者输入及其属性与采用管道输入的任何参数均不匹配。
3
  1. 5|Get-Random 5
复制代码
Get-Random : 无法将输入对象绑定到命令的任何参数,可能是因为该命令没有采用管道输入,或者输入及其属性与采用管道输入的任何参数均不匹配。
2

TOP

额,ps7.3中的说明
Get-Random [[-Maximum] <Object>] [-SetSeed <int>] [-Minimum <Object>] [-Count <int>] [<CommonParameters>]
不就表明-Maximum,-Count都是可选的选项?因此可以像Get-Random -Count 3 -Maximum 10这样使用
而ps5.1的说明
Get-Random [[-Maximum] <Object>] [-SetSeed <int>] [-Minimum <Object>]  [<CommonParameters>]
只有-Maximum这一个可选选项(-Count是另外一条语法中的可选选项)

Parameter是为了实现函数重载那样的功能,不同的ParameterSetName中的参数(选项)又不能混合使用

TOP

至少以ps5.1内置帮助来看,并不存在Get-Random -Count 3 -Maximum 10 这种用法,反正我就当它不存在
而且-count只是随机次数,要求不严简单迭代一下就行

TOP

返回列表