如何清理错误的 Azure PowerShell 卸载?

How to clean up bad Azure PowerShell uninstall?

背景: 我通过 MSI 安装了 Azure-PowerShell 1.x,随后通过命令提示符添加了一些 Azure 资源管理模块。 一切正常;然后昨天下午 ISE 莫名其妙地消失了。为了解决这个问题,我计划卸载 MSI,然后重新安装。 (我不知道有必要先卸载手动添加的模块。) 卸载似乎 运行 正常,但它没有删除手动安装的模块,也没有警告我。

结果:机器不再安装 Azure-PowerShell。我无法安装、卸载或修复安装,因为一些模块仍然存在:

Azure Modules from the PowerShell Gallery are installed on this machine. Please remove these modules before installing this MSI.

有没有办法"fix"这个安装?手动删除 files/cleanup 注册表,或强制 MSI 安装覆盖现有的任何内容?

这就是 运行在 Azure 上的 VM 上完成的全部内容。如果有必要,我可以删除整个 VM 并从头开始,但如果有相对简单的修复,我宁愿避免这种情况。

谢谢!

尝试通过 MSI(首先)卸载模块,然后使用 cmdline:

# Uninstall the AzureRM component modules
Uninstall-AzureRM

# Uninstall AzureRM module
Uninstall-Module AzureRM

# Uninstall the Azure module
Uninstall-Module Azure

# Or, you can nuke all Azure* modules
# Uninstall-Module Azure* -Force

之后重启机器,然后通过WebPI/MSI再次安装。 https://azure.microsoft.com/en-us/blog/azps-1-0/

这只是一个开发虚拟机。我核对了它并重新开始。经验教训:卸载 MSI 之前先卸载 PowerShell Gallery 组件。

好的,所以我尝试了以上项目来删除 windows powershell,发现实际上它并没有完全删除 powershell。

这至少在 windows 7 上似乎不正确。

如果你 运行 uninstall-module AzureUninstall-Module AzureRM 它会卸载一些东西,看起来像我认为的基本模块。

那么如果你这样做:

Get-Module AzureRM -ListAvailable

会白白回来的。 所以它做对了吗?

不,不是。

如果你这样做:

Get-Module -ListAvailable AzureRM*

你会发现任意数量的子模块仍然在那里。 (出于某种原因,通配符适用于 Get-Module 但不适用于 Uninstall-Module)

好吧,然后就执行 Uninstall-Module AzureRm* 吧? 不不不

取决于你的 powershell 版本(或者可能不是,我不确定) Install-Module 只是抱怨您不能在 Uninstall-Module 命令中使用通配符。 (天知道为什么如果不是这个通配符有什么意义?,但是这是 windows 所以我不得不接受它)。

如果您查看 %System-root%\Program Files\windowspowershell\modules,您仍然会在那里看到模块。

这是为什么?我不确定,但这是我必须做的清理所有旧版本和新版本的 Azure powershell,我必须回到干净的状态。 因此,为了解决缺少通配符支持的问题,我只是使用了一个 foreach 循环:

foreach ($module in (Get-Module -ListAvailable AzureRM*).Name |Get-Unique) { write-host "Removing Module $module" Uninstall-module $module }

注意不要尝试将此 运行 作为 Visual Studio 代码或 visual studio ,因为根据您的锁,您可能会遇到错误,因为它倾向于预加载模块并锁定打开的东西。把它放在一个名为 Removeold-AzureRM 的文件中。ps1 和 运行 从 powershell 控制台 window 像这样: .\Remove-AzureRM.ps1

另外请确保在尝试之前关闭 Visual Studio 代码和 Visual studio,否则您可能仍会收到类似的错误消息。

如果您在卸载 AzureRM 后 运行 这样做,您会发现一切都停止了,您只有最后一招。 删除 %System-root%\Program Files\windowspowershell\modules

中的所有 AzureRM 模块

编辑我已经重新测试了这个,如果你安装了 azurerm 5.0.1 并且你已经删除了 azurerm,上面的代码似乎仍然有效,所以我对其他的可能是错误的还有版本

现在您肯定会对此进行排序,现在您可以使用 Install-Module AzureRM 重新安装 Azure powershell。

如果你像我一样不小心犯了 powershellget 的错误,请不要尝试用 WMF 5.1 或 5.0 重新安装它,因为这样可以安装,但你仍然没有 powershellget,为什么我没有当然,这是 windows 所以让我们接受吧。

好的,那怎么解决呢?

您唯一的办法是下载 powershellget

的版本

然后将 PowerShellGet-1.5.0.0\PowerShellGet 复制到您的模块文件夹。 然后 Install-Module 将再次工作。

是的,我知道我们都在说重新安装不是更安全吗?

可能是,但对于像我这样的人来说,出于某种原因无法选择上述内容是您最好的选择。我希望这对某人有所帮助,因为我至少花了 3 天的时间才弄清楚为什么在我确定我已经删除了所有内容的情况下我仍然继续执行旧模块。

为了更快,您可以并行卸载:

workflow Uninstall-AzureModules
{
    $Modules = (Get-Module -ListAvailable Azure*).Name |Get-Unique
    Foreach -parallel ($Module in $Modules)
    { 
        Write-Output ("Uninstalling: $Module")
        Uninstall-Module $Module -Force
    }
}
Uninstall-AzureModules
Uninstall-AzureModules   #second invocation to truly remove everything

我发现命令 Get-InstalledModule 更适合我发现已安装的模块。

我最新的脚本是这样的:

# If installed, remove the old AzureRm module
$allModules = Get-InstalledModule
foreach ($module in $allModules)
{
    if ($module.Name -match "AzureRM.*")
    {
        Write-Host "Removing $($module.Name)..."
        Uninstall-Module -Name $module.Name -Force -AllVersions
    }
}

# If not installed, install the new Az module
$azModule = Get-InstalledModule -Name Az
if (!$azModule)
{
    Install-Module -Name Az -Scope CurrentUser -AllowClobber -Force
}

# Enable AzureRm aliases for script compat
Enable-AzureRmAlias -Scope LocalMachine

我在@BlueSky 答案上创建了这个变体以保留一个特定版本及其依赖项:

workflow Uninstall-AzureModules
{
    $skip = Find-Module AzureRM -RequiredVersion 2.1.0
    $dependencies = $skip.Dependencies | %{ Get-Module -FullyQualifiedName @{ ModuleName=$_["Name"]; RequiredVersion=$_["RequiredVersion"] } -ListAvailable }

    $modules = Get-Module azurerm* -ListAvailable | 
        where { $_.Version -ne '2.1.0' } |
        where { -Not(Compare-Object $dependencies $_ -IncludeEqual -ExcludeDifferent) }

    foreach -parallel ($module in $modules)
    { 
        Write-Output ("Uninstalling: $($module.Name) $($module.Version)")
        Uninstall-Module -Name $module.Name -RequiredVersion $module.Version -Force -ea SilentlyContinue
    }
}

这对我来说不起作用。我在 Powershell v7.02 MACOS v10.15.6 上。这段代码起作用了:

Function Uninstall-AzureModules
{
    $Modules = (Get-Module -ListAvailable Azure*).Name |Get-Unique
    Foreach ($Module in $Modules)
    { 
        Write-Output ("Uninstalling: $Module")
        Uninstall-Module $Module -Force
    }
}
Uninstall-AzureModules
Uninstall-AzureModules

我他们验证了 AzureRM 模块:

Get-InstalledModule -Name AzureRM*