Powershell 如何修改脚本以硬编码" | export-csv c:tempfilename.csv -notypeinformation"



我有一个很棒的脚本,我用它来生成一个文件夹列表,其中包含他们分配的安全组和每个组中的每个用户。

当我运行它时,我键入.getfolderacls.ps1 -verbose | export-csv c:tempfilename.csv -notypeinformation.

这非常有效,但我想对| export-csv...部分进行硬编码,以便我可以在没有参数(或者它们是参数?

我尝试简单地将| export-csv c:temptest.csv -notypeinformation附加到脚本的底部,但这会使错误An empty pipe element is not allowed

脚本:

[CmdletBinding()]
Param (
[ValidateScript({Test-Path $_ -PathType Container})]
[Parameter(Mandatory=$false)]
[string]$Path       
)
Write-Verbose "$(Get-Date): Script begins!"
Write-Verbose "Getting domain name..."
$Domain = (Get-ADDomain).NetBIOSName
Write-Verbose "Getting ACLs for folder $Path"
Write-Verbose "...and all sub-folders"
Write-Verbose "Gathering all folder names, this could take a long time on bigger folder trees..."
$Folders = Get-ChildItem -Path I:foldername -Directory -Recurse -Depth 2
Write-Verbose "Gathering ACL's for $($Folders.Count) folders..."
ForEach ($Folder in $Folders)
{   Write-Verbose "Working on $($Folder.FullName)..."
$ACLs = Get-Acl $Folder.FullName | ForEach-Object { $_.Access | where{$_.IdentityReference -ne "BUILTINAdministrators" -and $_.IdentityReference -ne "BUILTINUsers"  }}
ForEach ($ACL in $ACLs)
{   If ($ACL.IdentityReference -match "\")
{   If ($ACL.IdentityReference.Value.Split("")[0].ToUpper() -eq $Domain.ToUpper())
{   $Name = $ACL.IdentityReference.Value.Split("")[1]
If ((Get-ADObject -Filter 'SamAccountName -eq $Name').ObjectClass -eq "group")
{   ForEach ($User in (Get-ADGroupMember $Name -Recursive | Select -ExpandProperty Name))
{   $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = $Name
User = $User
FileSystemRights = $ACL.FileSystemRights
         }
$Result | Select Path,Group,User,FileSystemRights
}
}
Else
{    $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = ""
User = Get-ADUser $Name | Select -ExpandProperty Name
FileSystemRights = $ACL.FileSystemRights
}
$Result | Select Path,Group,User,FileSystemRights
}
}
Else
{   $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = ""
User = $ACL.IdentityReference.Value
FileSystemRights = $ACL.FileSystemRights
}
$Result | Select Path,Group,User,FileSystemRights
}
}
}
}
Write-Verbose "$(Get-Date): Script completed!"

脚本的输出是在foreach循环中生成的 -ForEach ($Folder in $Folders) ...(而不是通过ForEach-Objectcmdlet,不幸的是,该cmdlet也别名为foreach)。

为了foreach循环的输出发送到管道,您可以将其包装在脚本块({ ... })中,并使用点源运算符(.)调用它。 或者,使用调用运算符(&),在这种情况下,循环在子作用域中运行

以下是简化的示例:

# FAILS, because you can't use a foreach *loop* directly in a pipeline.
PS> foreach ($i in 1..2) { "[$i]" } | Write-Output
# ...
An empty pipe element is not allowed. 
# ...

# OK - wrap the loop in a script block and invoke it with .
PS> . { foreach ($i in 1..2) { "[$i]" } } | Write-Output
[1]
[2]

注意:我使用Write-Output作为可以管道连接到的 cmdlet的示例,仅用于此演示。在您的情况下,需要的是将您的foreach循环包装在. { ... }中,并遵循| Export-Csv ...而不是Write-Output

使用. { ... }& { ... }将循环内生成的输出逐个发送到管道,也称为流式处理方式- 就像cmdlet生成的输出(通常)发生的那样。


另一种方法是使用$(...),子表达式运算符(或@(...),数组子表达式运算符,在这种情况下,在通过管道发送之前,循环输出会作为一个整体预先收集在内存中 - 这通常更快,但需要更多的内存

# OK - call via $(...), with output collected up front.
PS> $(foreach ($i in 1..2) { "[$i]" }) | Write-Output
[1]
[2]

要在代码上下文中拼写出. { ... }解决方案 - 添加的行标有# !!!注释(另请注意根据Lee_Dailey对问题的注释改进代码的潜力):

[CmdletBinding()]
Param (
[ValidateScript({Test-Path $_ -PathType Container})]
[Parameter(Mandatory=$false)]
[string]$Path       
)
Write-Verbose "$(Get-Date): Script begins!"
Write-Verbose "Getting domain name..."
$Domain = (Get-ADDomain).NetBIOSName
Write-Verbose "Getting ACLs for folder $Path"
Write-Verbose "...and all sub-folders"
Write-Verbose "Gathering all folder names, this could take a long time on bigger folder trees..."
$Folders = Get-ChildItem -Path I:foldername -Directory -Recurse -Depth 2
Write-Verbose "Gathering ACL's for $($Folders.Count) folders..."
. { # !!!
ForEach ($Folder in $Folders) 
{   Write-Verbose "Working on $($Folder.FullName)..."
$ACLs = Get-Acl $Folder.FullName | ForEach-Object { $_.Access | where{$_.IdentityReference -ne "BUILTINAdministrators" -and $_.IdentityReference -ne "BUILTINUsers"  }}
ForEach ($ACL in $ACLs)
{   If ($ACL.IdentityReference -match "\")
{   If ($ACL.IdentityReference.Value.Split("")[0].ToUpper() -eq $Domain.ToUpper())
{   $Name = $ACL.IdentityReference.Value.Split("")[1]
If ((Get-ADObject -Filter 'SamAccountName -eq $Name').ObjectClass -eq "group")
{   ForEach ($User in (Get-ADGroupMember $Name -Recursive | Select -ExpandProperty Name))
{   $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = $Name
User = $User
FileSystemRights = $ACL.FileSystemRights
          }
$Result | Select Path,Group,User,FileSystemRights
}
}
Else
{    $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = ""
User = Get-ADUser $Name | Select -ExpandProperty Name
FileSystemRights = $ACL.FileSystemRights
}
$Result | Select Path,Group,User,FileSystemRights
}
}
Else
{   $Result = New-Object PSObject -Property @{
Path = $Folder.Fullname
Group = ""
User = $ACL.IdentityReference.Value
FileSystemRights = $ACL.FileSystemRights
}
$Result | Select Path,Group,User,FileSystemRights
}
}
}
}
} | Export-Csv c:temptest.csv -notypeinformation  # !!!
Write-Verbose "$(Get-Date): Script completed!"

相关内容

  • 没有找到相关文章

最新更新