Powershell 学习 管道传输

数不对齐时:自定义属性

上一篇文章中我们介绍了使用ByPropertyName 管道传输,通过Import csv文件中的数据来传递给下一个命令作为输入。其实当我们认为创建一些数据时,使用CSV是非常简单的一种方式。但是如果需要你处理一些其他人提供的数据时,格式可能并不是你想要的,可能问题就会变得比较麻烦。

New-ADUser

该命令属于活动目录中的一个模块,存在与Win server 2008 R2 及之后版本的操作系统域控制器中。

New-ADUser命令包含大量参数,每个参数用来匹配一个新的活动目录账号的信息,比如:

  • -Name (该参数必须存在)
  • -samAccountName(从语法的角度讲,可以不提供,但是为了使AD账户可用,仍然需要提供)
  • -Department
  • -City
  • -Title

这个命令需要在一定的环境上去运行,可能你的 环境并不能运行,我们现在只用跟随案例进行下去就可以了。

改命令其实还有更多的参数,但是我们目前只介绍这些参数,这些参数都是按照ByPropertyName方式接收管道的输出的。

接下来你需要处理一个csv文件,但是该文件来自于公司的HR,你可能已经多次要求他们按照某种特定的格式给出文件,但是他们最终依然固执的使用自己的格式如下图;

 

如上图所示,Powershell成功导入该CSV 文件,最终产生了三个对象,并且每个对象包含了四个属性。但是现在存在一个问题,dept属性与New-ADUser的-Department参数并不吻合,同事login属性是毫无意义的,这里并没有包含-samAccountName 或者-Name属性,所以如果你想通过一下的命令来创建新用户,必须指定这两个属性;

Import-Csv .\newuser.csv | New-AdUser

我们可以通过这样的方式来解决这个问题:


PS C:\Users\Meg\Desktop> Import-Csv .\newuser.csv |
>> Select-Object -Property *,
>> @{name='samAccountName';expression={$_.login}},
>> @{label='Name';expression={$_.login}},
>> @{n='Department';e={$_.Dept}}
>>


login          : Donj
dept           : IT
city           : Las Vegas
title          : CTO
samAccountName : Donj
Name           : Donj
Department     : IT

login          : Gregs
dept           : Custodial
city           : Denver
title          : Janitor
samAccountName : Gregs
Name           : Gregs
Department     : Custodial

login          : JeffH
dept           : IT
city           : Syracuse
title          : netWork
samAccountName : JeffH
Name           : JeffH
Department     : IT

接下来我们分析一下上边地方命令:

  • 这里我们使用了Select-Object命令以及它的-property参数,最开始,我们指定了*这个属性(*是指所有存在的属性),在*后面,我们使用了逗号,意味着我们还会输入其他的一些属性列。
  • 之后我们创建了一个哈系表,哈希表的结构是以  @{ 开始,以 } 结束。哈希表中包含了一个或者多个成对的键-值(key-value)数据。我们使用select-object去寻找我们指定的一些特定键。
  • select-object需要寻找的第一个键可以是: Name、N 、Label或者L,该键对应的值也就是我们想创建的属性的名称。在第一个哈希表中,我们指定了sameAccountName,第二个哈希表中,我们指定了Name,第三个哈希表中是Department。 这三个名称正好可以对应到New-AdUser命令的三个参数。
  • select-object需要的第二个键可以是Expression或者E。该键对应的值是一个包含在大括号 {} 中的脚本块。在脚本块中,使用特定的$_占位符,关联到已经存在的管道对象(csv文件中的每行的数据)。 通过$_可以读取管道对象的属性,或者说是csv文件中的一个列。也就是说,通过这种方法来指定新的属性值

括号命令

有些时候,第二个命令的参数并不接受来自管道的输入,那我们需要使用圆括号来解决这种问题。

如上图所示,Get-WmiObject 命令的 -CmputerName并不接受来自管道的输入。我们可以通过圆括号来解决这个问题。如下:Get-WmiObject -Class win32_bios -ComputerName (Get-Content .\computer.txt)

可见括号命令是很强大的,因为它根本不依赖于参数管道绑定,他会将获取的对象强制匹配到正确的参数。但是如果括号中输出的对象类型和需要绑定的参数类型不一致,也是会有问题出现的,那么我们接下来介绍一下该如何解决这种问题。

提取属性的值

很多时候,我们不会从一个静态的文件中获取计算机名称,比如可能需要从活动目录中获取某些数据。借助于ActiveDirectory模块,我们可以查看与控制服务器(domain controller)上的所有信息。

Get-ADComputer -Filter * -SearchBase "ou=domain controllers,dc=r4011408dom,dc=net"

你可以使用括号将上面命令的输出结果传递给get-service吗?

Get-Service -ComputerName (Get-ADComputer -Filter * -SearchBase "ou=domain controllers,dc=r4011408dom,dc=net“)

很遗憾,该命令并不能执行,因为get-secrvice命令的-computerName参数需要的是一个String类型的参数,然而通过gm命令我们可以知道,括号中的命令输出的结果并不是String类型的:

该命令的输出是ADComputer类型的,然而对象中包含了一个-name 属性,我们要做的就是将该属性的值提取出来,然后将这个值传递给get-service命令。

select-object命令中包含了一个可以接收属性名称的参数: -expandProperty, 它会获取对应的属性,提取属性的值,然后返回这些值(作为Select-Object的输出结果),参考如下命令:

Get-ADComputer -Filter * -SearchBase "ou=domain controllers,dc=r4011408dom,dc=net" |Select-Object -ExpandProperty name

该命令返回一个包含计算机名称的清单,里面的值可以传递给get-service命令的-computerName参数,

Get-Service -ComputerName (Get-ADComputer -Filter * -SearchBase "ou=domain controllers,dc=r4011408dom,dc=net" |Select-Object -ExpandProperty name)

Note:

一般情况下,类似select-object -property Name这种命令命令只会返回一个Name的属性(因为我们指定了该名称),-ComputerName参数不期望得到任意的-Name属性的对象,他更期望得到一个String类型的对象,因为这样会更简单。

-ExpandName会获取name属性,并且提取其值,最终该命令会输出一些比较简单的String类型的对象。

 

 

 

猜你喜欢

转载自blog.csdn.net/weixin_42545594/article/details/81669299