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-SqlCmdcmdlets:The obsolete
Invoke-SqlCmdcommand from the obsoleteSQLPSmodule.The current
Invoke-SqlCmdcommand from the successor module,SQLServerSee SQL Server PowerShell for background information.
However, since you're both apparently using the modern
SQLServermodule, the difference comes down to what version of that module you're using:-TrustServerCertificateparameter (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-SqlCmdcommand originates, which theGet-Commandcall implicitly auto-loads in the process.Note that both the obsolete
SqlPsand the modernSqlServermodule may be present, and for each there may be multiple versions.That is why it is important to run the
Get-Commandcall 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-SqlCommandthen refers to that module's command.Get-Module -ListAvailable SqlServer, SqlPslists 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
SqlPsmodule.Remove all but the latest version of the
SqlServermodule.If the use of
Uninstall-Modulefails, despite running with elevation - usually because the target module wasn't installed withInstall-Moduleto 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
SqlServermodule can be downloaded from the PowerShell Gallery, i.e. can be installed with, e.g.,Install-Module-Force SqlServer.