[求助] PowerShell无法使用Import-Csv 导入数组


PowerShell交流中心分类: 变量-函数-脚本-条件-循环-参数[求助] PowerShell无法使用Import-Csv 导入数组
0
Alan Chiu asked 8 年 ago

目前需要写一个批量修改邮件群组寄送限制的脚本,限制仅允许清单人员可以寄送邮件到邮件群组内,但遇到一个问题,使用Import-CSV无法从CSV文件内导入数组作为变量使用,还请各位大大指教,谢谢!
范例如下:

$Groups = Import-csv 'D:\Groups.csv'

foreach($Group in $Groups){
    Set-ADGroup $Group.Name -Clear dLMemSubmitPerms
    Set-ADGroup $Group.Name -Clear authOrig
    Set-ADGroup $Group.Name -Add @{authOrig = $Group.DN}
}

Groups.csv内容如下:
Name,DN
EmailGroup,”CN=EmailGroup,OU=Groups,DC=Test,DC=COM”,”CN=CompanyGroup,OU=Groups,DC=Test,DC=COM”
如果手动在PowerShell执行如下命令是可以成功将指定Object加入允许清单,但如果使用for循环将指定文件内的DN批量加入允许清单是失败的。
还望各位大大指教,谢谢!

Set-ADGroup EmailGroup -Add @{authOrig = "CN=EmailGroup,OU=Groups,DC=Test,DC=COM","CN=CompanyGroup,OU=Groups,DC=Test,DC=COM"}

 

Mooser Lee 管理员 replied 8 年 ago

你这csv格式,不是很清晰,能不能多几条数据,让我先看看csv的结构

1 Answers
0
Mooser Lee 管理员 answered 8 年 ago

我们先研究你给的csv文件格式:

Name,DN
EmailGroup1,"CN=EmailGroup,OU=Groups,DC=Test,DC=COM","CN=CompanyGroup,OU=Groups,DC=Test,DC=COM"
EmailGroup2,"CN=EmailGroup,OU=Groups,DC=Test,DC=COM","CN=CompanyGroup,OU=Groups,DC=Test,DC=COM"
EmailGroup3,"CN=EmailGroup,OU=Groups,DC=Test,DC=COM","CN=CompanyGroup,OU=Groups,DC=Test,DC=COM"

第一行是两列,Name,DN

第二行其实是3列,

  1. EmailGroup1
  2. “CN=EmailGroup,OU=Groups,DC=Test,DC=COM”
  3. “CN=CompanyGroup,OU=Groups,DC=Test,DC=COM”

可能还会有更多。

这样通过Import-Csv导入以后,我们先看看输出:

PS D:\> Import-Csv .\MailGroup.csv

Name        DN                                    
----        --                                    
EmailGroup1 CN=EmailGroup,OU=Groups,DC=Test,DC=COM
EmailGroup2 CN=EmailGroup,OU=Groups,DC=Test,DC=COM
EmailGroup3 CN=EmailGroup,OU=Groups,DC=Test,DC=COM

很明显,只读到了2列,因为第一行的头只有Name,和DN两个。

最终导致你自己脚本循环中的$Group.DN其实是一个string。

PS D:\> (Import-Csv .\MailGroup.csv)[0].DN.GetType().FullName
System.String

然后研究你的Set-ADGroup EmailGroup -Add 后面的参数可知authOrig的值是一个字符串数组

这样肯定就会导致参数不匹配。

=============================================

从这里分隔,看解决方案

综上所述,因为该csv文件的特殊格式,坑在于csv的头个数和csv的数据行个数不匹配。既然头多了可以,但是不能少,那我们就不要用csv文件中的头,自己给他加头,加多少呢?5个,还是10个,反正多多益善。

下面就不废话了,直接上脚本了:

#自定义csv文件头
$customHeader = @("Group")
#假设DN后面最多有5个
$maxDNColumns = 5
1..$maxDNColumns | foreach {
$customHeader+="CN$_"
}

Get-Content .\MailGroup.csv | 
 select -Skip 1 | #忽略源文件中的头
  ConvertFrom-Csv -Header $customHeader | #加入我们自己定义的头
  foreach {
    $group = $_.Group
    $dnPara = @()
    
    #循环获取CN1到CN...N的值,拼接成字符串数组
    for($dnIndex=1;$dnIndex -le $maxDNColumns;$dnIndex++ ){
        $value = $_."CN$dnIndex"
        if( -not [string]::IsNullOrWhiteSpace($value)){
        $dnPara+=$value
        }
        else{
            break;
        }
    }
    ##这里再执行你那关键的业务命令
    Set-ADGroup $group -Add @{authOrig = $dnPara}
  }
Alan Chiu replied 8 年 ago

Mooser, Thanks for your great help!!
在执行时会出现如下错误信息,确信只读2列的问题已解决,Set-ADGroup 却无法识别到$group,手动执行变量确认获取的参数无误:
Set-ADGroup : The name reference is invalid
At line:27 char:5
+ Set-ADGroup $group -Add @{authOrig = $dnPara}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (KQ1K00.Test.Group:ADGroup) [Set-ADGroup], ADException
+ FullyQualifiedErrorId : The name reference is invalid,Microsoft.ActiveDirectory.Management.Commands.SetADGroup

#手动执行变量:
PS D:\> $group
KQ1K00.Test.Group

PS D:\> $dnPara
CN=KQ1K00.Test.Group,OU=Groups,DC=Test,DC=COM
CN=KQ1K10.Test.Group,OU=Groups,DC=Test,DC=COM
CN=KQ1K20.Test.Group,OU=Groups,DC=Test,DC=COM
CN=KQ1K30.Test.Group,OU=Groups,DC=Test,DC=COM

Mooser Lee 管理员 replied 8 年 ago

显然参数解析已经是对的了。问题出在,KQ1K00.Test.Group 这个Name,我没有用过AD环境,无法给出答复。但是从The name reference is invalid的字面意思可知,该group不能设置该配置。你的设置是add操作,会不会是因为重复设置的缘故,最好在设置之前通过什么命令检查一下,是否已经存在,如果存在,先删除然后再添加。

Mooser Lee 管理员 replied 8 年 ago

还要对Group的合法性做出检测,比如这个Group是否存在,是否状态被标记为了已删除。通过关键字The name reference is invalid在谷歌中搜索出的绝大多数问题都是,引用了已经删除的对象。

Alan Chiu replied 8 年 ago

Group确认是存在的,稍后我再确认一下根本的原因,非常感谢您的再次帮助!

0
KIVIN answered 8 年 ago

如果是exchange服务器,用DL来控制可以发送到群组的账号不是更方便?

Alan Chiu replied 8 年 ago

邮件群组的数量较多,如果使用DL来控制,需要为每个群组建立策略,更为浪费时间,且会增加Exchange服务器的负载。所以不如直接修改AD Object。