powershell@管道符过滤的顺序问题@powershell管道符如何工作

文章目录

    • select 和 where谁先执行
    • powershell管道符
      • stop-service 为例查看文档中的典型参数介绍
      • stop-process为例介绍管道符传参是怎么工作的
        • Id参数
        • InputObject 参数
        • Name参数
        • 额外的试验
        • 反面例子
        • 应用:get-process 和stop-process配合

select 和 where谁先执行

  • 在执行筛选时,指定命令的顺序确实很重要。

  • 例如,考虑这样一种情况:使用 Select-Object 只选择几个属性(比如Name,Date),而使用 Where-Object 过滤的属性是(size)不在选择范围内的属性。在这种情况下,必须先进行过滤,否则在尝试执行过滤时,管道中将不存在该属性。

  • 下面的例子返回的内容会是空的

    Get-Service -ErrorAction Ignore |
    Select-Object -Property DisplayName, Running, Status |
    Where-Object CanPauseAndContinue
    
  • 更改select和where的顺序,就是正确的用法

    PS>Get-Service -ErrorAction Ignore |
    >> Where-Object CanPauseAndContinue |
    >> Select-Object -Property DisplayName, Status
    
    DisplayName                                           Status
    -----------                                           ------
    Control Center Hotkey Service                        Running
    Intel(R) Dynamic Tuning Technology Telemetry Service Running
    Intel(R) Graphics Command Center Service             Running
    Intel(R) Innovation Platform Framework Service       Running
    Workstation                                          Running
    Web Threat Defense Service                           Running
    Web Threat Defense User Service_1bd31e               Running
    Windows Management Instrumentation                   Running
    

powershell管道符

  • 这里解释powershell管道符是如何工作的,编写支持管道符的函数另见它文(阅读本文有助于理解和编写这类支持管道符函数)

  • One-liners and the pipeline - PowerShell | Microsoft Learn ~ 单行代码和管道 - PowerShell | Microsoft Learn

  • 我们知道,有些命令可以接受管道符传递过来的参数,例如

    • Stop-Service,简写别名为spsv
    • Stop-process,简写为spps
  • 下面介绍它们怎么处理管道符输入

stop-service 为例查看文档中的典型参数介绍

  • 为了说明问题,这里截取了stop-service的部分参数的文档

    • 这里截取的是三个典型的参数

      ...
      -DisplayName <String[]>
          Specifies the display names of the services to stop. Wildcard characters are
          permitted.
      
          Required?                    true
          Position?                    named
          Default value                None
          Accept pipeline input?       False
          Accept wildcard characters?  false
      
      -InputObject <ServiceController[]>
          Specifies ServiceController objects that represent the services to stop. Enter a
          variable that contains the objects, or type a command or expression that gets the
          objects.
      
          Required?                    true
          Position?                    0
          Default value                None
          Accept pipeline input?       True (ByValue)
          Accept wildcard characters?  false
      
      -Name <String[]>
          Specifies the service names of the services to stop. Wildcard characters are
          permitted.
      
          Required?                    true
          Position?                    0
          Default value                None
          Accept pipeline input?       True (ByPropertyName, ByValue)
          Accept wildcard characters?  false
      ...
      
    • 当一个参数同时接受按属性名和值输入的管道输入时,它总是先尝试按值输入。

    • 如果按值输入失败,它就会尝试按属性名输入。

    • 按值输入有点误导。我更喜欢称之为按类型。这意味着如果你将产生 ServiceController 对象类型的命令结果导入 Stop-Service,它会将该输入绑定到 InputObject 参数。

    • 但如果将产生字符串输出的命令结果导入 Stop-Service,则会将其绑定到 Name 参数。

    • 如果将一条不产生 ServiceController 或 String 对象的命令的结果导入 Stop-Service,不意味着绑定一定失败

    • 如果它产生(返回)的某个对象的属性包含了Name,那么它会将输出中的 Name 属性绑定到 Stop-Service 的 Name 参数。

stop-process为例介绍管道符传参是怎么工作的

  • 经典命令stop-process,结束进程的cmdlet

    •   -Id <System.Int32[]>
              Specifies the process IDs of the processes to stop. To specify multiple IDs, use commas to separate the IDs. To
               find the PID of a process, type `Get-Process`.
      
              Required?                    true
              Position?                    0
              Default value                None
              Accept pipeline input?       True (ByPropertyName)
              Accept wildcard characters?  false
      
          -InputObject <System.Diagnostics.Process[]>
              Specifies the process objects to stop. Enter a variable that contains the objects, or type a command or express
              ion that gets the objects.
      
              Required?                    true
              Position?                    0
              Default value                None
              Accept pipeline input?       True (ByValue)
              Accept wildcard characters?  false
      
          -Name <System.String[]>
              Specifies the process names of the processes to stop. You can type multiple process names, separated by commas,
               or use wildcard characters.
      
              Required?                    true
              Position?                    named
              Default value                None
              Accept pipeline input?       True (ByPropertyName)
              Accept wildcard characters?  true
      
  • 为了便于介绍,这里创建两个notepad进程

    • PS C:\Users\cxxu\Desktop> $pss=ps Notepad
      PS C:\Users\cxxu\Desktop> $pss
      
       NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
       ------    -----      -----     ------      --  -- -----------
           44    74.81     123.38       0.58     440   1 Notepad
           12     2.70      13.02       0.02   21176   1 Notepad
      
Id参数
  • 可以看到,Id参数接受管道符的输入,并且是管道符前的表达式输出的对象包含名为Id的属性(而且属性值类型兼容<System.Int32[]>时才会被绑定到这个参数上
InputObject 参数
  • 然而stop-process还有其他参数支持管道符的形式输入,例如InputObject,并且通常具有更高的优先级,因为powershell管道符传参时,优先检查ByValue的参数,然后才是ByPropertyName的参数

  • 正如前面所讲的那样,文档里面InputObject是带有类型的,类型为<System.Diagnostics.Process[]>,当管道符前面的表达式产生的刚好是这个类型的对象,那么就会被InputObject所捕获绑定

  • 执行$pss|stop-Process仿佛执行的是以下遍历语句

    foreach ($p in $pss){
    	stop-process -InputObject $p
    }
    
    
  • 在PowerShell中,-InputObject 参数通常用于指定直接传递给 cmdlet 的输入对象。

  • 例如参数声明 -InputObject <System.Diagnostics.Process[]>,其中<System.Diagnostics.Process[]> 表示 InputObject 参数应该是 System.Diagnostics.Process 类型的对象数组,这个类型代表系统中的进程。

  • 这种参数类型经常用于那些接收进程作为输入的cmdlet,比如 Stop-Process

  • 例如,如果你有一个 System.Diagnostics.Process 对象的数组,你可以使用 Stop-Process cmdlet 来结束这些进程:

    # 获取所有名为 "notepad" 的进程对象的数组
    $processes = Get-Process -Name "notepad"
    
    # 将进程对象数组传递给 Stop-Process cmdlet 来结束这些进程
    Stop-Process -InputObject $processes
    
    • 在这个例子中,-InputObject 参数接收了一个 Process 对象的数组,然后 Stop-Process cmdlet 将结束数组中的每一个进程。

    • 当你直接使用 -InputObject 参数时,通常不需要通过管道传递对象,因为你已经直接提供了要处理的对象数组。

Name参数
  • Id参数类似,当管道符传入的对象包含了Id属性,并且类型为<System.String[]>时,有机会绑定到这个参数上
额外的试验
  • 我们提到说管道符输入时,会分别检查byValue和byPropertyName类型的参数

  • 下面自定义一个类型,然后看看通过管道符传递能否按照预期工作

  • 自定义一个类型,包含一个字段Name,值为notepad

    $custObj = [PSCustomObject]@{
        Name = 'notepad'
    }
    
  • 检查$custObj对象的成员

    PS C:\repos\scripts> $custObj = [PSCustomObject]@{
    >>     Name = 'notepad'
    >> }
    PS C:\repos\scripts> $custObj | Get-Member
    
       TypeName: System.Management.Automation.PSCustomObject
    
    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    Name        NoteProperty string Name=notepad
    
    • 可以发现powershell会自定让其继承一些必要的成员方法和特殊属性
  • 使用这个对象传递给Stop-Service

    • #启动一个notepad进程,用来试验杀死
      PS C:\repos\scripts>  notepad
      #将$custObj传递给Stop-Process,检验其是否能够解析出$custObj对象中有Name属性,从而杀死所有Name为notepad的进程
      PS C:\repos\scripts> $custObj | Stop-Process   
      
    • 经过检验,上述语句顺利执行

反面例子
  • PS> 'notepad'|Stop-Process
    Stop-Process: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
    
    • 输入对象无法绑定到该命令的任何参数,原因可能是该命令不接受管道输入,或者输入及其属性与接受管道输入的任何参数都不匹配。

    • 在这个例子中,语句尝试传递一个字符串notepadstop-process,我们可以猜测其意图是杀死所有名为notepad的进程,然而stop-process不支持这种用法,不会达到以下语句的效果

      • stop-process -name 'notepad'
        
    • stop-process的所有参数中,有3个参数会尝试绑定来自管道符的输入,正如文档指出的,Id,InputObject,Name三个参数,并且都有各自的类型要求,注明在了文档中

      • 其中IdName都是ByPropertyName类型的,而InputObject优先级高,是ByValue型的
      • 上述反面例子中,管道符前的字符串notepad不是InputObject要求的类型,因此不会被绑定到InputObject
      • notepad作为字符串对象,没有IdName属性,自然也不会绑定到IdName参数
    • 综上,字符串作为管道符传递给stop-process必然报错

  • 事实上,stop-process第一个默认的位置参数是Id,也就是进程号,而不是进程对应的程序名字

    • 这是合理的,因为一个程序可能有多个运行示例,例如notepad被打开多个进程,而我们要关闭notepad时可能要保留其中的一个或者只想关闭其中的具体某一个,为了防止轻易关闭所有进程造成误杀,因此要显式使用-Name参数指出您确实想要关闭所有具有指定程序名字的进程
    • 否则您应该通过get-process来查看相关进程,然后记住或者复制Id号,执行stop-process <Id>
应用:get-process 和stop-process配合
  • 假设有以下对象

    • PS> $pss=get-process notepad
      PS>$pss
      
       NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
       ------    -----      -----     ------      --  -- -----------
           47    73.11     117.62       0.17   12772   1 Notepad
           13     2.83      12.51       0.00   13768   1 Notepad
      
  • 我们看看$pss对象能否传递给stop-process这个cmdlet呢?

    • 利用Get-Member(alias:gm)来检查$pss对象的成员(属性,成员函数等),这个输出通常是比较长的

      • 事实上,传递给gm的如果是一个容器类型(比如数组),那么gm返回的是容器保存的对象的类型

      • 例如某个变量是包含2个字符串的数组,那么传给gm返回的是字符串类型的成员列表

      • 我们检查以下$pss是什么类型,调用对象的.GetType()方法即可

        PS> $pss.GetType()
        
        IsPublic IsSerial Name                                     BaseType
        -------- -------- ----                                     --------
        True     True     Object[]                                 System.Array
        
        • 可以看到,$pss的类型是一个数组(可迭代对象)
    • 这里看看$pss数组中的对象有哪些成员,以便于我们对$pss进一步处理,比如便利迭代等操作

      PS C:\Users\cxxu\Desktop> $pss|gm
      
         TypeName: System.Diagnostics.Process
      
      Name                       MemberType     Definition
      ----                       ----------     ----------
      Handles                    AliasProperty  Handles = Handlecount
      Name                       AliasProperty  Name = ProcessName
      NPM                        AliasProperty  NPM = NonpagedSystemMemorySize64
      PM                         AliasProperty  PM = PagedMemorySize64
      SI                         AliasProperty  SI = SessionId
      VM                         AliasProperty  VM = VirtualMemorySize64
      WS                         AliasProperty  WS = WorkingSet64
      Parent                     CodeProperty   System.Object Parent{get=GetParentProcess;}
      Disposed                   Event          System.EventHandler Disposed(System.Object…
      ErrorDataReceived          Event          System.Diagnostics.DataReceivedEventHandle…
      Exited                     Event          System.EventHandler Exited(System.Object, …
      OutputDataReceived         Event          System.Diagnostics.DataReceivedEventHandle…
      BeginErrorReadLine         Method         void BeginErrorReadLine()
      BeginOutputReadLine        Method         void BeginOutputReadLine()
      CancelErrorRead            Method         void CancelErrorRead()
      ...
      Id                         Property       int Id {get;}
      MachineName                Property       string MachineName {get;}
      MainModule                 Property       System.Diagnostics.ProcessModule MainModul…
      MainWindowHandle           Property       System.IntPtr MainWindowHandle {get;}
      ...
      
    • 我们可以利用group来统计一下结果,比如我们gm返回的结果,按照对象的成员的各种类型来统计

      • PS> $pss|gm |group -Property MemberType
        
        Count Name                      Group
        ----- ----                      -----
            7 AliasProperty             {Handles = Handlecount, Name = ProcessName, NPM = No…
            1 CodeProperty              {System.Object Parent{get=GetParentProcess;}}
           52 Property                  {int BasePriority {get;}, System.ComponentModel.ICon…
            1 NoteProperty              {string __NounName=Process}
            8 ScriptProperty            {System.Object CommandLine {get=…
            2 PropertySet               {PSConfiguration {Name, Id, PriorityClass, FileVersi…
           19 Method                    {void BeginErrorReadLine(), void BeginOutputReadLine…
            4 Event                     {System.EventHandler Disposed(System.Object, System.
      • 可以看到,$pss中的对象包含的成员的类型有8种,最重要的两类是Property,Method

    • PS C:\Users\cxxu\Desktop> $pss|gm |?{$_.Name -eq 'Id'}
      
         TypeName: System.Diagnostics.Process
      
      Name MemberType Definition
      ---- ---------- ----------
      Id   Property   int Id {get;}
      
    • 回到stop-process,经过上面的操作可知,get-process返回的对象(如果是数组,自动迭代其中的元素)包含了名为Id的属性,那么可以通过管道接受Get-Process的输出

      • PS> $pss|Stop-Process
        
      • 上述命令会杀死所有$pss中列出的进程,仿佛执行的是

        • foreach ($p in $pss){
              stop-process -id $p.Id
          }
          
  • 处理上面的$pss是一个包含多个进程对象的数组情况以外,也可以处理单个进程的情况

    • 例如

      PS[BAT:84%][MEM:37.91% (12.02/31.70)GB][21:36:45]
      # [~\Desktop]
      PS> ps gopeed
      
       NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
       ------    -----      -----     ------      --  -- -----------
           51   147.82     155.86     223.50   16432   1 gopeed
      
      
      PS[BAT:84%][MEM:37.91% (12.02/31.70)GB][21:36:47]
      # [~\Desktop]
      PS> $p=ps gopeed
      
      PS[BAT:84%][MEM:37.91% (12.02/31.70)GB][21:37:03]
      # [~\Desktop]
      PS> $p
      
       NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
       ------    -----      -----     ------      --  -- -----------
           52   148.82     157.17     223.62   16432   1 gopeed
      
      
      PS[BAT:84%][MEM:37.91% (12.02/31.70)GB][21:37:04]
      # [~\Desktop]
      PS> $p.GetType()
      
      IsPublic IsSerial Name                                     BaseType
      -------- -------- ----                                     --------
      True     False    Process                                  System.ComponentModel.Com…
      
      
      PS[BAT:84%][MEM:37.90% (12.02/31.70)GB][21:37:10]
      # [~\Desktop]
      PS> $p|gm
      
         TypeName: System.Diagnostics.Process
      
      Name                       MemberType     Definition
      ----                       ----------     ----------
      Handles                    AliasProperty  Handles = Handlecount
      Name                       AliasProperty  Name = ProcessName
      NPM                        AliasProperty  NPM = NonpagedSystemMemorySize64
      PM                         AliasProperty  PM = PagedMemorySize64
      
      ...
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/611401.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

灰狼优化算法(Grey Wolf Optimizer)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法引言 灰狼算法&#xff08;Grey Wolf Optimizer, GWO&#xff09;是一种受自然界灰狼行为启发的优化算法。它模拟了灰狼的社会层次和狩猎策…

JS实现初始化、动态点击切换激活样式

食用须知&#xff0c;不懂得把代码交给AI解释一下&#xff0c;明白流程就会用了&#xff0c;本文只有js与html&#xff0c;样式代码一概没有&#xff1a; 效果展示 1、点击显示的盒子代码 <div data-v-e1dd37c4"" class"news-container main-width-contain…

JAVA获取application.yml配置文件的属性值

application.yml配置参数 方式一&#xff1a;使用Value方式(常用) 语法 Value("${配置文件中的key:默认值}") Value("${配置文件中的key}")方法1&#xff1a;使用的类文件中定义变量&#xff0c;直接使用变量 import org.springframework.beans.factory.an…

通义千问2.5中文能力地表最强

随着人工智能技术的不断进步&#xff0c;智能问答系统已成为人们日常生活中不可或缺的一部分。阿里巴巴集团作为全球领先的科技公司&#xff0c;一直致力于AI领域的研发和创新。最近&#xff0c;阿里巴巴发布了其最新的智能问答系统——通义千问2.5。 通义千问2.5在AI问答领域…

抖音新店怎么对接达人?对接达人秘籍流程分享,让你学会找达人

大家好&#xff0c;我是电商花花。 新手怎么对接达人带货&#xff1f;这是我们新手商家 要考虑的问题。 很多新手抱怨自己新店铺不出单&#xff0c;没有销量&#xff0c;对接达人又怕达人看不上&#xff0c;没有达人愿意帮我带货&#xff0c;在面临这样的情况下不知道该怎么办…

基于自我对弈框架的偏好优化算法SPPO

传统的从人类反馈中进行强化学习&#xff08;RLHF&#xff09;的方法仰赖如Bradley-Terry模型等参数模型,但这样的模型难以充分捕捉人类偏好中的非递移性和非理性。最新的研究进展显示,直接使用偏好机率可以更准确地反映人类偏好,从而实现更灵活、更精确的语言模型对齐。本文提…

会话劫持攻击就在我们身边,我们要如何防范

会话劫持攻击&#xff08;Session Hijacking&#xff09;是一种网络攻击方式&#xff0c;攻击者通过某种手段获取到用户的会话标识&#xff08;Session ID&#xff09;&#xff0c;然后使用这个会话标识冒充合法用户进行恶意操作。这种攻击方式允许攻击者以合法用户的身份访问受…

Go语言系统学习笔记(一):基础篇

1. 写在前面 公司的新业务开发需要用到go语言&#xff0c;虽然之前没接触过这门语言&#xff0c;但在大模型的帮助下&#xff0c;边看项目边写代码也能进行go的项目开发&#xff0c;不过&#xff0c;写了一段时间代码之后&#xff0c;总感觉对go语言本身&#xff0c;我的知识体…

Python尝试安装 pyaudio 时遇到的错误信息表示安装过程失败,原因是找不到 Python.h 头文件

环境&#xff1a; Python 3.8.10 WSL2 问题描述&#xff1a; 尝试安装 pyaudio 时遇到的错误信息表示安装过程失败&#xff0c;原因是找不到 Python.h 头文件 error: subprocess-exited-with-error Building wheel for pyaudio (pyproject.toml) did not run successfully…

【数据结构】手把手带你玩转线性表

前言&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累。我…

Ubuntu 安装 samba 实现文件共享

1. samba的安装: sudo apt-get install samba sudo apt-get install smbfs2. 创建共享目录 mkdir /home/share sudo chmod -R 777 /home/share3. 创建Samba配置文件: 3.1 保存现有的配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak3.2 打开现有的文件 sudo…

基于小波交叉谱分析的地震波走时变化测量(MATLAB)

地震波在地球介质中传播&#xff0c;带来了丰富的地下介质物性的信息&#xff0c;为了解地球内部结构及运动变化提供了可能。地球内部地震波速度的差异是人们确定地球圈层结构和横向不均匀性的重要物理参数&#xff0c;地下介质应力的变化和积累是地震的孕育和发生的原因&#…

百面算法工程师 | 传统图像处理——OpenCV

本文给大家带来的百面算法工程师是传统图像处理的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们将介绍一些集几何变换和图像平滑处理&#xff0c;并提供参考的回答及其理论基础&…

分布式与集群的区别

先说区别&#xff1a; 分布式是并联工作的&#xff0c;集群是串联工作的。 分布式中的每一个节点都可以做集群。而集群并不一定就是分布式的。 集群举例&#xff1a;比如新浪网&#xff0c;访问的人很多&#xff0c;他可以做一个集群&#xff0c;前面放一个相应的服务器&…

微软必应bing国内广告开户费用?如何开户投放?

当下搜索引擎广告无疑是企业触达潜在客户、提升品牌曝光度的重要途径之一&#xff0c;微软必应&#xff08;Bing&#xff09;作为全球第二大搜索引擎&#xff0c;尽管在国内市场份额上可能不敌某些本土巨头&#xff0c;但其独特的用户群体和国际影响力使其成为众多企业拓展市场…

【强化学习入门】基于DDPG的强化学习控制器设计

最近在看控制领域研究热门–强化学习相关的东西&#xff0c;跟着matlab官方强化学习教程一边看一边学&#xff0c;感觉入门门槛略高&#xff0c;需要补很多机器学习相关的知识&#xff0c;高数概率论那些&#xff0c;摸索了个把月感觉现在只大概会用&#xff0c;原理啥的还没搞…

git 常用命令 git怎么撤销命令 持续更新中!!!!

基本流程 # 拉取仓库 git clone 仓库地址 # 拉取最新版本 git pull # 本地提交 git add . git commit -m "本次提交信息&#xff01;" # 推送上云 git push分支 # 创建分支 git checkout -b cart # 删除本机的分支 git branch -d cart # 切换分支 本地切换到主分支…

热爱电子值得做的电子制作实验

加我zkhengyang&#xff0c;进嵌入式音频系统研究开发交流答疑群(课题组) AM/FM收音机散件制作&#xff0c;磁带随声听散件&#xff0c;黑白电视机散件制作&#xff0c;功放散件制作&#xff0c;闪光灯散件制作&#xff0c;声控灯散件&#xff0c;等等&#xff0c;可提高动手能…

postman常用功能超全使用教程

Postman 使用 一、Postman 简介 Postman是一个接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求(如:get/post/delete/put…等等),将请求数据发送至服务端,获取对应的响应结果。 二、Postman 功能简介 三、Postman 下载安装 Post…

多模态模型Mini-Gemini:代码模型数据均开源,MiniCPM小钢炮2.0全家桶四连发,可以在Android 手机端上运行的大模型,效果还不错

多模态模型Mini-Gemini&#xff1a;代码模型数据均开源&#xff0c;MiniCPM小钢炮2.0全家桶四连发&#xff0c;可以在Android 手机端上运行的大模型&#xff0c;效果还不错。 多模态模型Mini-Gemini&#xff1a;代码模型数据均开源 香港中文大学终身教授贾佳亚团队提出多模态模…
最新文章