将Powershell中的对象重定向到其他功能

1合1

我有一个功能可以与用户比较进程,但是当我尝试将输出通过管道传递到停止进程时,出现以下错误:

“ Stop-Process:无法评估参数'InputObject',因为其参数被指定为脚本块且没有输入。如果没有输入,则无法评估脚本块。”

 Function Proc {

$TargetUsers = get-content oldusers.txt
$WmiArguments = @{

                'Class' = 'Win32_process'
            }

            $processes = Get-WMIobject @WmiArguments |      ForEach-Object {
                $Owner = $_.getowner();
                $Process = New-Object PSObject
                $Process | Add-Member Noteproperty 'ComputerName' $Computer
                $Process | Add-Member Noteproperty 'ProcessName' $_.ProcessName
                $Process | Add-Member Noteproperty 'ProcessID' $_.ProcessID
                $Process | Add-Member Noteproperty 'Domain' $Owner.Domain
                $Process | Add-Member Noteproperty 'User' $Owner.User
                $Process
            }



      ForEach ($Process in $Processes) {
               if ($TargetUsers -Contains $Process.User) {
               stop-process -id {$_.processid}

                    }

            }
              }

我已经阅读了有关Powershell中管道命令的服务器文章,并且它是基于对象的,但是我迷失了如何使用一个函数的返回对象并将其管道化为另一个函数,即使我确信当您知道如何简单时也是如此

史蒂文

我喜欢西奥的答案。我只想添加一些其他肯定不会包含在评论中的内容...

最初,我认为我们都在调试您的代码,但要保持最初设置的模式。严格来说,这没有错。

我认为您真正的问题是这里有些失落。为什么不能简单地将一个函数的输出传递给另一个函数呢?答案在于接收cmdlet或函数如何期待数据。

如果查看Get-Help Stop-Process -Parameter Id(OR参数名称),则会看到如果正确命名属性,它将通过管道获取该属性:

-Id <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

因此,如果您是自定义对象,则该管道具有名为“ Id”的属性。

Stop-Process 将接受进程ID,但它正在寻找的属性名称为“ Id”,并且Win32_Process返回“ ProcessID”。

但是,还有第二个问题。传入的属性值必须是接收函数/ cmdlet可接受的。不幸的是,Win32_Process通常会返回带有“ .exe”后缀的名称,并且Get-Process不会接受。

Theo的答案非常好并且可以使用,Stop-Process因为他的新对象具有一个名为“ ID”的属性,该属性被管道接受并且是默认参数集的一部分,这意味着它比name属性更受青睐。

但是,如果要将这些对象通过管道传输到Get-Process它,将无法正常工作。Get-Process与ID相比,它更喜欢名称,并且期望Win32_Process返回一个类似于“ notepad”而不是“ Notepad.exe”的值。在这种情况下,Get-Process它将无法找到进程,并且会出错。

注意:以上已根据与Theo的协作进行了更正,您可以查看以前的修订和注释以供参考。

为了使对象也可以使用,Get-Process只需修改进入“ Name”属性的值以删除结尾的“ .exe”即可。我编辑了Theo的答案只是为了补充一点。您应该看到他是否批准了。

我意识到这不是您最初的问题的一部分,而是要说明不同工具/ cmdlet /功能等之间管道的附加警告。

注意:可能仍然有几个例外。例如:Win32_Process返回“系统空闲进程”,但Get-Process返回“空闲”。为了您的目的,这可能不是问题。当然,您永远不会停止该过程!

注意:Get-Process首选名称而Stop-Process不是ID的可能原因是名称不是唯一的,而ID是。Stop-Process记事本将杀死记事本的所有实例,通常(在您的情况下)不是预期的。

关于一般方法。我指出了扩展对象和创建PS Custom对象的几种方法。Add-Member如果您需要或希望实例类型保持不变,则是一种好方法;我会考虑扩展对象。但是,在您的情况下,您要创建一个自定义对象,然后向其中添加成员。在这种情况下,我通常使用已经转换为PSCustomObjects的Select-Object。

您的代码具有更正的“名称”属性:$ Processes = Get-WmiObject win32_process

$Processes | 
ForEach-Object{
    $Owner = $_.getowner()
    $Process = New-Object PSObject
    $Process | Add-Member NoteProperty 'ComputerName' $_.CSName
    $Process | Add-Member NoteProperty 'ProcessName' $_.ProcessName
    $Process | Add-Member NoteProperty 'ProcessID' $_.ProcessID
    $Process | Add-Member NoteProperty 'Domain' $Owner.Domain
    $Process | Add-Member NoteProperty 'User' $Owner.User
    $Process | Add-Member NoteProperty 'Name' -Value ( $_.ProcessName -Replace '\.exe$' )
    $Process
}

注意:为简洁起见,我删除了一些周围的代码。

使用select看起来像:

$Processes = Get-WmiObject win32_process |
Select-Object ProcessID,
    @{Name = 'ComputerName'; Expression = { $_.CSName }},
    @{Name = 'Name ';        Expression = { $_.ProcessName -Replace '\.exe$' } },
    @{Name = 'Id';           Expression = { $_.ProcessID } },
    @{Name = 'Domain';       Expression = { $_.GetOwner().Domain} },
    @{Name = 'User';         Expression = { $_.GetOwner().User} }

然后,可以将其直接传递到where子句以过滤正在寻找的进程,然后再次传递给Stop-Processcmdlet:

Get-WmiObject win32_process |
Select-Object ProcessID,
    @{Name = 'ComputerName'; Expression = { $_.CSName }},
    @{Name = 'Name ';        Expression = { $_.ProcessName -Replace '\.exe$' } },
    @{Name = 'Id';           Expression = { $_.ProcessID } },
    @{Name = 'Domain';       Expression = { $_.GetOwner().Domain} },
    @{Name = 'User';         Expression = { $_.GetOwner().User} } |
Where-Object{ $TargetUsers -contains $_.User } |
Stop-Process

注意:这甚至将分配删除到$ Processes。您仍然需要填充$ TargetUsers变量。

另外:较早的评论指出,鉴于您正在做的事,不需要所有道具,例如:

Get-WmiObject win32_process |
Select-Object @{Name = 'Name '; Expression = { $_.ProcessName -Replace '\.exe$' } },
    @{Name = 'User'; Expression = { $_.GetOwner().User} } |    
Where-Object{ $TargetUsers -contains $_.User } |
Stop-Process

但是,如果您在代码中执行其他操作,例如记录终止的进程,则建立和维护更多属性相对而言是无害的。

仅出于说明目的,也可以ForEach-Object相对轻松地简化管道布置,而无需偏离原始对象:

Get-WmiObject win32_process | 
Where{$TargetUsers -contains $_.GetOwner().User } |
ForEach-Object{ Stop-Process -Id $_.ProcessID }

关于PowerShell的最好的事情之一就是有很多做事的方法。最后一个例子非常简洁,但是添加诸如日志记录或控制台输出之类的东西并不是最佳选择(尽管可行)。

另外,西奥(Theo)关于Get-CimInstance是正确的。如果我没记错的话Get-WmiObject,不推荐使用。旧习惯很难打破,因此我使用了所有示例。Get-WmiObject但是,这些概念应适用于整个PowerShell,包括Get-CimInstance...

无论如何,我希望我在这里添加了一些内容。那里有几篇文章讨论了不同的对象创建和操作功能的优缺点等...如果有时间,我将尝试对其进行跟踪。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用React功能组件重定向到其他页面

来自分类Dev

将根/主页重定向到自定义页面会破坏.htaccess中的所有其他重定向

来自分类Dev

将调试和STDOUT重定向到其他文件

来自分类Dev

将调用动态重定向到其他程序集?

来自分类Dev

将唯一URL重定向到其他URL

来自分类Dev

将输出重定向到其他路径

来自分类Dev

将产品重定向到其他网站

来自分类Dev

将调用动态重定向到其他程序集?

来自分类Dev

将特定URL的请求重定向到其他URL

来自分类Dev

使用.htaccess将URL重定向到其他域

来自分类Dev

将 Azure Web 应用中的子站点重定向到其他站点

来自分类Dev

将管理员重定向到其他页面,将用户重定向到其他页面

来自分类Dev

对数组中的每个对象执行多项功能,然后将结果重定向到文件

来自分类Dev

htaccess:在将某些用户代理重定向到其他域的同时重定向整个域?

来自分类Dev

无法重定向到其他网页

来自分类Dev

按钮重定向到其他页面

来自分类Dev

重定向到其他PHP页面

来自分类Dev

Laravel 重定向到其他路由

来自分类Dev

重定向到其他网站

来自分类Dev

将所有输出重定向到PowerShell中的文件

来自分类Dev

将shell的输出重定向到带有“&”号的文件,并在输出中返回一些其他命令

来自分类Dev

想要在webview android中完成URL加载后将webview重定向到其他意图

来自分类Dev

301将子目录中的www和其他子域重定向到非www

来自分类Dev

想要在webview android中完成URL加载后将webview重定向到其他意图

来自分类Dev

Google自定义搜索的优化功能不会重定向到其他网站。

来自分类Dev

Google自定义搜索的优化功能不会重定向到其他网站。

来自分类Dev

将单个页面从其他域重定向到主域会导致太多重定向

来自分类Dev

登录后将IdentityServer4重定向到其他客户端

来自分类Dev

将空的URL子域重定向到其他目录?

Related 相关文章

  1. 1

    使用React功能组件重定向到其他页面

  2. 2

    将根/主页重定向到自定义页面会破坏.htaccess中的所有其他重定向

  3. 3

    将调试和STDOUT重定向到其他文件

  4. 4

    将调用动态重定向到其他程序集?

  5. 5

    将唯一URL重定向到其他URL

  6. 6

    将输出重定向到其他路径

  7. 7

    将产品重定向到其他网站

  8. 8

    将调用动态重定向到其他程序集?

  9. 9

    将特定URL的请求重定向到其他URL

  10. 10

    使用.htaccess将URL重定向到其他域

  11. 11

    将 Azure Web 应用中的子站点重定向到其他站点

  12. 12

    将管理员重定向到其他页面,将用户重定向到其他页面

  13. 13

    对数组中的每个对象执行多项功能,然后将结果重定向到文件

  14. 14

    htaccess:在将某些用户代理重定向到其他域的同时重定向整个域?

  15. 15

    无法重定向到其他网页

  16. 16

    按钮重定向到其他页面

  17. 17

    重定向到其他PHP页面

  18. 18

    Laravel 重定向到其他路由

  19. 19

    重定向到其他网站

  20. 20

    将所有输出重定向到PowerShell中的文件

  21. 21

    将shell的输出重定向到带有“&”号的文件,并在输出中返回一些其他命令

  22. 22

    想要在webview android中完成URL加载后将webview重定向到其他意图

  23. 23

    301将子目录中的www和其他子域重定向到非www

  24. 24

    想要在webview android中完成URL加载后将webview重定向到其他意图

  25. 25

    Google自定义搜索的优化功能不会重定向到其他网站。

  26. 26

    Google自定义搜索的优化功能不会重定向到其他网站。

  27. 27

    将单个页面从其他域重定向到主域会导致太多重定向

  28. 28

    登录后将IdentityServer4重定向到其他客户端

  29. 29

    将空的URL子域重定向到其他目录?

热门标签

归档