Powershell如何将脚本修改为硬代码导出csv c:\temp\filename.csv-notypeinformation“;
我有一个很棒的脚本,用来生成文件夹列表,其中包含分配的安全组和每个组中的每个用户 当我运行它时,我键入Powershell如何将脚本修改为硬代码导出csv c:\temp\filename.csv-notypeinformation“;,powershell,syntax,scriptblock,Powershell,Syntax,Scriptblock,我有一个很棒的脚本,用来生成文件夹列表,其中包含分配的安全组和每个组中的每个用户 当我运行它时,我键入\getfolderacls.ps1-verbose | export csv c:\temp\filename.csv-notypeinformation 这很好,但是我想硬编码| export csv…部分,这样我就可以在没有参数(或者是参数)的情况下运行它 我尝试简单地将| export csv c:\temp\test.csv-notypeinformation添加到脚本底部,但这会引发
\getfolderacls.ps1-verbose | export csv c:\temp\filename.csv-notypeinformation
这很好,但是我想硬编码| export csv…
部分,这样我就可以在没有参数(或者是参数)的情况下运行它
我尝试简单地将| export csv c:\temp\test.csv-notypeinformation
添加到脚本底部,但这会引发错误不允许使用空管道元素
脚本:
[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 "BUILTIN\Administrators" -and $_.IdentityReference -ne "BUILTIN\Users" }}
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($Folders中的文件夹)…
中生成的(与通过foreach对象
cmdlet相反,不幸的是,该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]
注意:我使用写入输出作为您可以通过管道连接到的cmdlet示例,仅用于本演示目的。在您的案例中,需要将您的foreach
循环包装在中。{…}
并使用|导出Csv…
而不是写入输出
使用。{…}
或&{…}
将循环中生成的输出一个接一个地发送到正在生成的管道中,即以流式方式发送——就像cmdlet生成的输出(通常)一样
另一种方法是使用$(…)
、子表达式操作符(或@(…)
、数组子表达式操作符,在这种情况下,循环输出作为一个整体预先收集在内存中,在通过管道发送之前-这通常更快,但需要更多内存:
# OK - call via $(...), with output collected up front.
PS> $(foreach ($i in 1..2) { "[$i]" }) | Write-Output
[1]
[2]
拼写。{…}
在代码上下文中导出解决方案-添加的行用#标记代码>注释(同时注意根据Lee_Dailey对该问题的评论改进代码的可能性):
脚本的输出是在foreach
循环-foreach($Folders中的文件夹)…
中生成的(与通过foreach对象
cmdlet相反,不幸的是,该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]
注意:我使用写入输出作为您可以通过管道连接到的cmdlet示例,仅用于本演示目的。在您的案例中,需要将您的foreach
循环包装在中。{…}
并使用|导出Csv…
而不是写入输出
使用。{…}
或&{…}
将循环中生成的输出一个接一个地发送到正在生成的管道中,即以流式方式发送——就像cmdlet生成的输出(通常)一样
另一种方法是使用$(…)
、子表达式操作符(或@(…)
、数组子表达式操作符,在这种情况下,循环输出作为一个整体预先收集在内存中,在通过管道发送之前-这通常更快,但需要更多内存:
# OK - call via $(...), with output collected up front.
PS> $(foreach ($i in 1..2) { "[$i]" }) | Write-Output
[1]
[2]
拼写。{…}
在代码上下文中导出解决方案-添加的行用#标记代码>注释(同时注意根据Lee_Dailey对该问题的评论改进代码的可能性):
这些重复的行$Result |选择路径、组、用户、文件系统权限
似乎是您的输出。在其上方添加一行,输出所需的CSV。类似于$Result | Export Csv-Path“$env:temp\Report.Csv”-Append./////作为旁白,您为什么在那里使用
Select Object`呢?看起来您只是在确保道具的顺序。如果是这样,您可以通过用New Object PSObject-Property@{/code>替换[PSCustomObject]@{
。这将保持您的定义顺序。[grin]感谢您的响应,Lee_Dailey。当我用[PSCustomObject]@{替换新对象PSObject-Property@{时,我收到错误:“Get-ADGroupMember:此请求的大小限制在C:\Temp\Get_folder_acls_Test.ps1:26 char:40+…{ForEach($User in)处被超过(Get-ADGroupMember$Name-Recursive | Selec…+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~类别信息:未指定:(域用户:ADGroup)[Get ADGroupMember],这是一个例外,因为这两个命令的结果几乎相同……这意味着你不小心更改了其他结果中唯一的区别是项目将以声明的顺序结束&您不再需要选择对象
在输出对象中指定属性顺序。这些重复行$result |选择路径、组、用户、文件系统权限