我想将基本文件夹包含在子目录列表中。
如果我使用Get-ChildItem并搜索文件夹:
$startFolder = "C:\Scripts"
Get-ChildItem $startfolder -recurse |
Where-Object {$_.PSIsContainer -eq $True} |
Select FullName
我得到一个像这样的子文件夹列表:
C:\Scripts\folder1
C:\Scripts\folder2
C:\Scripts\folder2\folderA
我想看看:
C:\Scripts <-- include the starting folder
C:\Scripts\folder1
C:\Scripts\folder2
C:\Scripts\folder2\folderA
我在technet上看到了一个像这样的例子:
$startFolder = "C:\Scripts"
$colItems = (Get-ChildItem $startFolder | Measure-Object -property length -sum)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB"
$colItems = (Get-ChildItem $startFolder -recurse | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object)
foreach ($i in $colItems)
{
$subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum)
$i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB"
}
他们把它分成两部分。处理起始文件夹,然后处理子文件夹。这是唯一的方法,还是可以将起始文件夹包含在一个命令中?
看起来这么简单......
答案 0 :(得分:1)
一个解决方案:
$startFolder = "C:\Scripts"
$(Get-Item $startFolder
Get-ChildItem $startfolder -recurse |
Where-Object {$_.PSIsContainer -eq $True}) |
Select FullName
为您的$ startFolder添加Get-Item
,并将其与Get-ChildItem
中的sub-expression
一起包装在同一个集合中。
答案 1 :(得分:0)
如果您不喜欢这种行为,请进行更改。如果使用这两行,则可以获取代理函数的框架:
$MetaData = New-Object System.Management.Automation.CommandMetaData (Get-Command Get-ChildItem)
[System.Management.Automation.ProxyCommand]::Create($MetaData)
然后您可以在过程块中添加此代码:
$GetItemParams = @{
Force = $Force
}
switch ($PSCmdlet.ParameterSetName) {
Items { $GetItemParams.Path = $Path }
LiteralItems { $GetItemParams.LiteralPath = $LiteralPath }
default {
Write-Error "Unable to call Get-Item on base: Unknown ParameterSetName"
}
}
Get-Item @GetItemParams
执行此操作后,您的最终代理功能将如下所示:
function Get-ChildItem {
[CmdletBinding(DefaultParameterSetName='Items', SupportsTransactions=$true, HelpUri='http://go.microsoft.com/fwlink/?LinkID=113308')]
param(
[Parameter(ParameterSetName='Items', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]
${Path},
[Parameter(ParameterSetName='LiteralItems', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
${LiteralPath},
[Parameter(Position=1)]
[string]
${Filter},
[string[]]
${Include},
[string[]]
${Exclude},
[Alias('s')]
[switch]
${Recurse},
[switch]
${Force},
[switch]
${Name})
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
# Modification starts here
$GetItemParams = @{
Force = $Force
}
switch ($PSCmdlet.ParameterSetName) {
Items { $GetItemParams.Path = $Path }
LiteralItems { $GetItemParams.LiteralPath = $LiteralPath }
default {
Write-Error "Unable to call Get-Item on base: Unknown ParameterSetName"
}
}
Get-Item @GetItemParams
# Modification ends here
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
$steppablePipeline.End()
} catch {
throw
}
}
<#
.ForwardHelpTargetName Get-ChildItem
.ForwardHelpCategory Cmdlet
#>
}
当然,如果您不想在每次尝试使用Get-ChildItem时调用您的函数,您可以将该函数命名为您想要的任何内容。
答案 2 :(得分:0)
我喜欢文件系统安全性PowerShell模块3.2.3(NTFSSecurity),它允许使用长文件名并包含-Directory标志,因此我的解决方案适用于:
((Get-Item2 -Path $startFolder -ErrorAction SilentlyContinue),
(Get-ChildItem2 -Path $startFolder -Recurse -Directory -ErrorAction SilentlyContinue)).FullName |
ForEach-Object {
process-folder $_ ...
}