如何使用 get-childitem 将基本文件夹包含在子文件夹列表中?
How do I include the base folder in the list of sub-folders using get-childitem?
我想将基本文件夹包含在子目录列表中。
如果我使用 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"
}
他们把它分成两部分。处理起始文件夹,然后处理子文件夹。这是唯一的方法还是可以将起始文件夹包含在一个命令中?
原来是这么简单的事情...
一个解决方案:
$startFolder = "C:\Scripts"
$(Get-Item $startFolder
Get-ChildItem $startfolder -recurse |
Where-Object {$_.PSIsContainer -eq $True}) |
Select FullName
为您的 $startFolder 添加一个 Get-Item
,并将其与您的 Get-ChildItem
一起包装在一个 sub-expression
中,这样它们都在同一个集合中。
如果您不喜欢这种行为,请改变它。如果你使用这两行,你可以获得代理函数的框架:
$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 时都调用您的函数,您可以随意命名该函数。
我喜欢文件系统安全 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 $_ ...
}
我想将基本文件夹包含在子目录列表中。
如果我使用 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"
}
他们把它分成两部分。处理起始文件夹,然后处理子文件夹。这是唯一的方法还是可以将起始文件夹包含在一个命令中?
原来是这么简单的事情...
一个解决方案:
$startFolder = "C:\Scripts"
$(Get-Item $startFolder
Get-ChildItem $startfolder -recurse |
Where-Object {$_.PSIsContainer -eq $True}) |
Select FullName
为您的 $startFolder 添加一个 Get-Item
,并将其与您的 Get-ChildItem
一起包装在一个 sub-expression
中,这样它们都在同一个集合中。
如果您不喜欢这种行为,请改变它。如果你使用这两行,你可以获得代理函数的框架:
$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 时都调用您的函数,您可以随意命名该函数。
我喜欢文件系统安全 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 $_ ...
}