Question:
I am trying to update the PSFTP module from the gallery. I used Remove-Module
, but these three (3) aliases remain. How can I remove them before installing the current PSFTP module?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
PS C:\src\t\ftp> Get-Command *ftp* CommandType Name Version Source ----------- ---- ------- ------ Alias Move-FTPItem 1.6.1.2 PSFTP Alias Receive-FTPItem 1.6.1.2 PSFTP Alias Send-FTPItem 1.6.1.2 PSFTP Function Get-SFTPChildItem 2.0.2 Posh-SSH Function Get-SFTPContent 2.0.2 Posh-SSH ... PS C:\src\t\ftp> Remove-Item -Path Alias:Move-FTPItem Remove-Item : Cannot find path 'Alias:\Move-FTPItem' because it does not exist. At line:1 char:1 + Remove-Item -Path Alias:Move-FTPItem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Alias:\Move-FTPItem:String) [Remove-Item], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand |
Additional information
I am not sure how PSFTP
got onto this machine. Using Uninstall-Module
, even under Run as Administrator, does not work. How might I correctly uninstall this module?
1 2 3 4 5 6 7 8 |
PS C:\Windows\system32> Uninstall-Module -Name PSFTP PackageManagement\Uninstall-Package : No match was found for the specified search criteria and module names 'PSFTP'. At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:2157 char:21 + ... $null = PackageManagement\Uninstall-Package @PSBoundParameters + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Microsoft.Power...ninstallPackage:UninstallPackage) [Uninstall-Package], Exception + FullyQualifiedErrorId : NoMatchFound,Microsoft.PowerShell.PackageManagement.Cmdlets.UninstallPackage |
The module directory does exist on the machine.
1 2 |
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSFTP |
Answer:
Remove-Module
unloads a module, but doesn’t remove it from the filesystem.
With $PSModuleAutoLoadingPreference
at its default (All
), this means that the module and its commands are still discoverable, even if the module isn’t currently loaded (imported).
As it happens, this particular module exports only aliases, which is why only they show up in the output from Get-Command *ftp*
.
While Get-Command
is able to find aliases from not-currently-loaded (imported) modules, such aliases are not present in the Alias:
drive and attempts to remove them with Remove-Item Alias:<name>
or, more directly, Remove-Alias <name>
fail.
If you want to uninstall the module before installing a new version – assuming you’ve installed it from the PowerShell Gallery, as you say (see update below) – use Uninstall-Module
.
That said, in order to update an installed module, simply use Update-Module
.
Note that this performs a side-by-side installation, however: while the newest version does take effect, the previous version is retained and requires manual removal, if desired.
If the module wasn’t installed from the PowerShell Gallery, manual deletion of its folder is required:
- Be sure that no other modules depend on the module to delete.
- To find a module’s dependents, i.e., other modules that depend on it, use, e.g. (I’m using module
PackageManagement
as an example, which has modulePowerShellGet
as a dependent):
123Get-Module -ListAvailable |Where-Object { $_.RequiredModules.Name -contains 'PackageManagement' }- Note, however, that there could be scripts that also rely on this module, and such uses would be much harder to detect (short of searching all scripts for
#requires -Module
directives,using -module statements
,Import-Module
calls, or simply calls to the module’s commands that relied on auto-loading the module).
- Note, however, that there could be scripts that also rely on this module, and such uses would be much harder to detect (short of searching all scripts for
- To perform the inverse operation, i.e. to find a module’s dependencies, if any (the modules a given module itself depends on), use, e.g.:
(Get-Module -ListAvailable PowerShellGet).RequiredModules
(there will be no output if there are no dependencies),- Similarly, as @lit (the OP) points out, you can query a module available in the PowerShell Gallery for its dependencies online; e.g.:
Find-Module -IncludeDependencies PowerShellGet
(this will list the module itself first, followed by its dependencies).
- To find a module’s dependents, i.e., other modules that depend on it, use, e.g. (I’m using module
- Depending on the module’s installation location, you may need administrative privileges for removal (an elevated session).
- This is definitely the case for
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSFTP
.
Note that, as a third-party module,PSFTP
should never have been installed there, becauseC:\Windows\System32\WindowsPowerShell\v1.0\Modules
($PSHOME\Modules
) is reserved for system modules (the ones that ship with PowerShell). - Once you’ve confirmed that it is safe to delete the module folder, use the following (remove the
-WhatIf
to perform actual deletion):
12Remove-Item -Recurse -Force -WhatIf C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSFTP
- This is definitely the case for
Determining a module’s location (installation folder):
- By module name (e.g.,
PSFTP
):
12Split-Path (Get-Module -ListAvailable PSFTP).Path-ListAvailable
ensures that the module is found even if it is not currently imported, but only if it is is located in one of the directories listed in$env:PSModulePath
.- Conversely, if a module is currently imported, but resides in a nonstandard directory, you most omit
-ListAvailable
in order to find it. - Multiple versions of a module may be installed and therefore be returned; the one with the highest version number is listed first.
- By the name of a command exported by the module (e.g.,
Send-FTPItem
):
12Split-Path (Get-Command Send-FTPItem).Module.PathGet-Command
finds the command whether or not the containing module is currently imported.- If a module containing a command by that name is currently loaded (imported), its path is returned.
- Otherwise, if multiple module versions are installed, the effective one is reported, which is the one with the highest version number.