有什么方法可以在PowerShell中使用rm -rf吗?

问题描述 投票:0回答:1

我知道我可以使用

rm -r -fo
在 PowerShell 中删除文件夹及其所有内容。但是有什么办法可以在 PowerShell 中使用
rm -rf
吗?

我尝试将以下脚本添加到我的

$Profile
中,但两者都不起作用。

  1. 第一次尝试:

    function rm -rf() {
        rm -r -fo
    }
    
  2. 第二次尝试:

    Set-Alias rm -rf "rm -r -fo"
    
powershell rm
1个回答
0
投票

按照评论中的建议,您可以编写一个代理函数,将

-rf
参数添加到
Remove-Item
。如果您随后将别名
rm
设置为指向您的代理函数而不是
Remove-Item
,您将能够像在 Unix 中一样使用
rm -rf MyDirectory
,同时仍然有机会使用
Remove-Item
的所有其他参数。您基本上将拥有
Remove-Item
additional 参数
-rf

iRon 的优秀问答中所述,您可以使用以下命令生成代理函数体:

$MetaData = [System.Management.Automation.CommandMetaData](Get-Command Remove-Item)
[System.Management.Automation.ProxyCommand]::Create($MetaData)

这会给你:

[CmdletBinding(DefaultParameterSetName='Path', SupportsShouldProcess=$true, ConfirmImpact='Medium', SupportsTransactions=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=113373')]
param(
    [Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
    [string[]]
    ${Path},

    [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [Alias('PSPath')]
    [string[]]
    ${LiteralPath},

    [string]
    ${Filter},

    [string[]]
    ${Include},

    [string[]]
    ${Exclude},

    [switch]
    ${Recurse},

    [switch]
    ${Force},

    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [pscredential]
    [System.Management.Automation.CredentialAttribute()]
    ${Credential})


dynamicparam
{
    try {
        $targetCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters)
        $dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object { $_.Value.IsDynamic })
        if ($dynamicParams.Length -gt 0)
        {
            $paramDictionary = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
            foreach ($param in $dynamicParams)
            {
                $param = $param.Value

                if(-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name))
                {
                    $dynParam = [Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
                    $paramDictionary.Add($param.Name, $dynParam)
                }
            }
            return $paramDictionary
        }
    } catch {
        throw
    }
}

begin
{
    try {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
        {
            $PSBoundParameters['OutBuffer'] = 1
        }
        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
        $scriptCmd = {& $wrappedCmd @PSBoundParameters }
        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}

process
{
    try {
        $steppablePipeline.Process($_)
    } catch {
        throw
    }
}

end
{
    try {
        $steppablePipeline.End()
    } catch {
        throw
    }
}
<#

.ForwardHelpTargetName Microsoft.PowerShell.Management\Remove-Item
.ForwardHelpCategory Cmdlet

#>

您可以将其直接粘贴到您自己的函数定义中,您将已经拥有一个与

Remove-Item
相同的函数。

要添加参数

-rf
,请添加以下参数定义:

[switch]
$rf

如果不直接将其传递给

Remove-Item
,请将以下行添加到
dynamicparam
块中:

$PSBoundParameters.Remove('rf') | Out-Null

然后,当提供了

Remove-Item
参数时,您只需要处理
-rf
的调用即可。为此,请将行
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
更改为:

if ($rf) {
    $scriptCmd = {& $wrappedCmd @PSBoundParameters -Recurse -Force }
} else {
    $scriptCmd = {& $wrappedCmd @PSBoundParameters }
}

在下面的完整示例中,我将代理函数命名为

rm2
并进行了我已经描述过的所有更改。最后我打电话给
Set-Alias
以使其可用。不用担心,
Set-Alias
只会影响您当前的会话,不会永久改变您的系统。您可以将以下块复制并粘贴到您的 PowerShell 配置文件中,每当您打开 PowerShell 会话时,您就可以使用
rm -rf
:

function rm2 {
    [CmdletBinding(DefaultParameterSetName='Path', SupportsShouldProcess=$true, ConfirmImpact='Medium', SupportsTransactions=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=113373')]
    param(
        [Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string[]]
        ${Path},

        [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('PSPath')]
        [string[]]
        ${LiteralPath},

        [string]
        ${Filter},

        [string[]]
        ${Include},

        [string[]]
        ${Exclude},

        [switch]
        ${Recurse},

        [switch]
        ${Force},

        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [pscredential]
        [System.Management.Automation.CredentialAttribute()]
        ${Credential},
        
        [switch]
        $rf)


    dynamicparam
    {
        try {
            $PSBoundParameters.Remove('rf') | Out-Null
            $targetCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters)
            $dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object { $_.Value.IsDynamic })
            if ($dynamicParams.Length -gt 0)
            {
                $paramDictionary = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
                foreach ($param in $dynamicParams)
                {
                    $param = $param.Value

                    if(-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name))
                    {
                        $dynParam = [Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
                        $paramDictionary.Add($param.Name, $dynParam)
                    }
                }
                return $paramDictionary
            }
        } catch {
            throw
        }
    }

    begin
    {
        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
            {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
            if ($rf) {
                $scriptCmd = {& $wrappedCmd @PSBoundParameters -Recurse -Force }
            } else {
                $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        } catch {
            throw
        }
    }

    process
    {
        try {
            $steppablePipeline.Process($_)
        } catch {
            throw
        }
    }

    end
    {
        try {
            $steppablePipeline.End()
        } catch {
            throw
        }
    }
    <#

    .ForwardHelpTargetName Microsoft.PowerShell.Management\Remove-Item
    .ForwardHelpCategory Cmdlet

    #>
}

Set-Alias -Name rm -Value rm2 -Option AllScope
© www.soinside.com 2019 - 2024. All rights reserved.