[英]powershell - Remove all variables
我想在脚本开始时删除所有用户创建的变量。
目前我正在执行Remove-Variable -Name *
但它也尝试删除所有系统变量,从而导致大量错误消息。
还有什么办法吗?
由于所有系统变量都是只读或常量,因此您可以将错误静音:
Remove-Variable * -ErrorAction SilentlyContinue
但不可否认,无论如何你应该排除一些:
Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
调用 PowerShell 的新实例,获取内置变量,然后删除不属于的所有其他内容。
$ps = [PowerShell]::Create()
$ps.AddScript('Get-Variable | Select-Object -ExpandProperty Name') | Out-Null
$builtIn = $ps.Invoke()
$ps.Dispose()
$builtIn += "profile","psISE","psUnsupportedConsoleApplications" # keep some ISE-specific stuff
Remove-Variable (Get-Variable | Select-Object -ExpandProperty Name | Where-Object {$builtIn -NotContains $_})
不是删除所有用户变量,而是启动一个新的 PowerShell 实例:
PS C:\> $x = 10
PS C:\> $y = 50
PS C:\> $blah = 'text'
PS C:\> Write-host $x $y $blah
10 50 text
PS C:\> powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
PS C:\> Write-host $x $y $blah
PS C:\>
用户定义的变量不会延续到新实例中。
PS C:\> $bleh = 'blue'
PS C:\> Write-Host $bleh
blue
PS C:\> exit
PS C:\> Write-host $bleh
PS C:\>
您的变量也不会返回到调用实例中。
关于如何实际实现这一点,您有几种选择。
当然,您始终可以自己启动新实例:
powershell -ExecutionPolicy Unrestricted -File myscript
你不应该依赖这些变量。 任何未声明的东西都不会被使用。 如果您需要传递信息,请使用参数。
如果您遵守这一原则,您只需覆盖用户创建的变量并像从未存在过一样使用它。
这是企业最佳实践,可让您无限扩展脚本。 不仅在 Powershell 中,而且在任何可以具有全局变量的语言中,例如 Javascript。
这是一个hack ,它将删除除 $profile 中创建的变量之外的所有变量。 请注意,这需要几秒钟才能运行,而且您很有可能以更有效的方式实现最终目标。 您必须调整 select 语句中的“15”以对应于您的配置文件脚本吐出的行数。 或者您可以修改它以从 gv (get-variable) 中搜索第一行。
$x=powershell -nologo -command "gv|out-string"
$y=($x|select -skip 15) -split "\s+",2
$varnames = $(for ($i=0;$i -lt $y.length; $i+=2) { $y[$i]})
rv i,x,y
gv | % {if ($varnames -notcontains $_.name) {rv $_.name -EA 0}}
警告:这不会删除 Powershell 主机创建的变量,这些变量指定了加载模块或执行创建变量的脚本的 InitialSessionState。 但是对于普通的 Powershell 和 powershell_ise,您不必担心。
我会将现有变量名称列表拉入脚本开头的数组中,然后删除脚本末尾的任何新添加的变量:
### Start of script (store list of existing variable names) $ExistingVariables = Get-Variable | Select-Object -ExpandProperty Name <# Script contents go here #> ### End of script (remove new variables) $NewVariables = Get-Variable | Select-Object -ExpandProperty Name | Where-Object {$ExistingVariables -notcontains $_ -and $_ -ne "ExistingVariables"} if ($NewVariables) { Write-Host "Removing the following variables:`n`n$NewVariables" Remove-Variable $NewVariables } else { Write-Host "No new variables to remove!" }
您还可以考虑更改变量的范围。 例如,包含在循环或函数中的变量仅存在于该范围内。 只要变量不是在全局或脚本范围内创建的,它们就不会在脚本完成后持续存在。 然后您可以删除全局/脚本范围变量。 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.1
使用乔伊的答案效果很好......也许太好了。 例如,当我在 Visual Studio Code 中使用时,它的$psEditor
变量被删除,它的集成终端开始抛出错误。
需要明确的是,我使用的是Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
作为我脚本的一部分,然后触发脚本的其余部分,以确保它处于干净的状态,但它被过度清理了。
我通过将$psEditor
添加到例外列表中来解决这个问题,如下所示:
Get-Variable -Exclude PWD,*Preference,psEditor | Remove-Variable -EA 0
但这是一种打地鼠方法,似乎有更好的方法,具体取决于您对相关脚本的控制程度。
例如,这是我在 GitHub 中提出的那个问题的来自SeeminglyScience的一个很好的解决方案,尽管它本质上减少了 ferrell_io 答案中的逻辑,并进行了一些重要改进:
$existingVariables = Get-Variable
try {
# your script here
} finally {
Get-Variable |
Where-Object Name -notin $existingVariables.Name |
Remove-Variable
}
说的是...
这是一个很好的“让它不比你发现的更糟”的解决方法。
也许值得一提的是,将重要变量留在范围内的 VS Code 集成终端并不完美, 对所提出问题的一些回应表示,他们可能会将$psEditor
更改$psEditor
常量,以便Remove-Variable
无法执行此操作意外破坏。
我想你可以列出你不想删除的所有变量。
$DontDelete = '$','?','^','args',...,'WhatIfPreference'
然后删除不在不要删除列表中的变量。
你不能。 您必须在脚本启动之前跟踪可用变量,并删除脚本执行后添加的任何变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.