I'm one of two SQL Server DBAs trying to use a PowerShell script and have run into a problem. The code I'm trying to run is:
$DSQLServer = 'VM-SQL119'
$Results = Invoke-SqlCmd -ServerInstance $DSQLServer -Database master -Query "SELECT @@ServerName" -TrustServerCertificate
When I run it on my desktop, it works. When the other DBA runs it, he gets:
Invoke-Sqlcmd : A parameter cannot be found that matches parameter name 'TrustServerCertificate'
Both our machines are running the same version of PowerShell:
$PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 19041 3570
I Googled how to find which module a cmdlet is coming from and, again, both our desktops return the same information:
(Get-Command -Name Invoke-sqlcmd).ModuleName
SqlServer
Can anyone shed some light on how the same command, in the same version of PowerShell, from the same module, can work on one machine and fail on the other?
Thanks in advance.
Ken
Fundamentally - unfortunately - there are two - technically distinct -
Invoke-SqlCmd
cmdlets:The obsolete
Invoke-SqlCmd
command from the obsoleteSQLPS
module.The current
Invoke-SqlCmd
command from the successor module,SQLServer
See SQL Server PowerShell for background information.
However, since you're both apparently using the modern
SQLServer
module, the difference comes down to what version of that module you're using:-TrustServerCertificate
parameter (emphasis and direct link added):To diagnose the problem:
In a pristine session, run:
which prints both the name and the version number of the (effective) module from which the
Invoke-SqlCmd
command originates, which theGet-Command
call implicitly auto-loads in the process.Note that both the obsolete
SqlPs
and the modernSqlServer
module may be present, and for each there may be multiple versions.That is why it is important to run the
Get-Command
call in a pristine session, i.e. one in which no third-party modules have been imported yet, given that code running in the session could explicitly import the wrong module or an older version, after whichInvoke-SqlCommand
then refers to that module's command.Get-Module -ListAvailable SqlServer, SqlPs
lists all versions of these two modules that are discoverable via auto-loading (i.e. via the directories listed in$env:PSModulePath
, in order). For a given module, the version listed first (if there are multiple) is the effective one, i.e. the one that will be auto-loaded.With two modules in the picture, whichever('s first version) is listed first is the effective one.
It's best to remove all obsolete versions - note that you may have to run with elevation (as administrator) if the modules to be removed were installed with
-Scope AllUsers
:Remove all versions of the obsolete
SqlPs
module.Remove all but the latest version of the
SqlServer
module.If the use of
Uninstall-Module
fails, despite running with elevation - usually because the target module wasn't installed withInstall-Module
to begin with - remove the underlying directories manually - which again may require elevation:List the candidate set of module directories:
Identify those to delete and pass them to
Remove-Item
-Recurse -Force
...\SqlServer\22.0.59
) and its parent directory (...\SqlServer
) ends up empty after removal, you can remove the latter too.The latest version of the
SqlServer
module can be downloaded from the PowerShell Gallery, i.e. can be installed with, e.g.,Install-Module
-Force SqlServer
.