SQL installed but powershell not picking up sqlps commands (like invoke-sqlcmd) - sql-server

I installed ms sql server with chocolatey:
choco install SQLServer2012DeveloperEditionWithSP1 -y -f -source 'http://choco.developers.tcpl.ca/chocolatey' -c "$env:WINDIR\temp"
SQL seems to be installed and working well outside of powershell where it doesn't work. I can see the sqlps module with:
Get-Module -listavailable
...
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0 SQLASCMDLETS
Manifest 1.0 SQLPS
The commands seem to be missing though. I don't have invoke-sqlcmd etc. In theory I should get access to them if I install the module but when I try to import-module sqlps but I get an error about not having a sqlserver drive:
PS C:\WINDOWS\system32> Import-Module SQLPS
Set-Location : Cannot find drive. A drive with the name 'SQLSERVER' does not exist.
At C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS\SqlPsPostScript.ps1:1 char:1
+ Set-Location SQLSERVER:
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (SQLSERVER:String) [Set-Location], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
I know several people in my group who went through these steps and did get the correct sql ps setup working.
Any tips or ideas would be very helpful. Thanks.

Good day,
I am guessing that you are using SQL Server 2017, since this is common issue in 2017, as I will explain below. I am not sure what version is used since this question is a bit old and was asked on May 2 '17 at 22:58
The error that you get includes the basic issue
Set-Location : Cannot find drive. A drive with the name 'SQLSERVER' does not exist.
It does not say that the module 'SQLPS' does not exist, but that the module 'SQLSERVER' does not exist
The explanation is that until 2016 SQLPS module was included with the SQL Server installation, but the PowerShell module which we use is the 'SqlServer' module. 'SqlServer' module was included with SQL Server Management Studio (SSMS) 16.x, but if you are using SSMS 2017 (17.x) then 'SqlServer' module must be installed from the PowerShell Gallery.
The procedure to install it is to execute the command:
Install-Module -Name SqlServer
If you get error like PackageManagement\Install-Package : The following commands are already available on this system:...
Then you can enforce the installation using the parameters: -Force and –AllowClobber
Since I am not familiar with your system, I will NOT advice you what to do or say if you should enforce the installation, but this is the solution which I would probably do in most cases like this (according to the information I noticed in this thread)
Install-Module -Name SqlServer -Force –AllowClobber
In order to confirm that the module is instead you can execute the following command:
Get-Module -Name SqlServer -listAvailable | select Name, ModuleType, Version
Check the version of your installation using the command above, and use it in the following command in order to import the newest version (at the time I write this answer the version is 21.0.17279):
Import-Module SqlServer -Version 21.0.17279
That is all... If all went well then you should be able to use all the SQL Server PowerShell commands

Just a side-note for future readers, I was trying to create a sql backup via powershell. The cmdlets ran as they should under an Administrator account, however running the script under a regular user account, I got the following error:
Cannot find a provider with the name 'SqlServer'
Googling that question brought me here, but the answer to my issue was in a forum post here:
https://social.technet.microsoft.com/Forums/windowsserver/en-US/626bb81a-00ba-4239-ad0a-fec32546350a/check-if-drive-exists-if-not-map?forum=winserverpowershell
I encountered a weird issue and hope that somebody may have a fix for this.
Microsoft SQL Server 2014 (SP2-GDR) (KB4505217) - 12.0.5223.6 (X64) (yeah I know...it's a dev server)
Windows 2012 R2
PSVersion 4.0
I load the SQL assemblies in the PS script
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
The following will fail if I run this immediately after loading the assemblies
Get-ChildItem SQLSERVER:\SQL$env:COMPUTERNAME
Get-ChildItem : Cannot find drive. A drive with the name 'SQLSERVER' does not exist.
If I run the following first, I'm fine.
Invoke-Sqlcmd -Query "SELECT TOP 1 * FROM sys.sysobjects" | Out-Null
Get-ChildItem SQLSERVER:\SQL$env:COMPUTERNAME
I just wanted to amend that I just need to run
Invoke-Sqlcmd | Out-Null
This seems to then fully load the assemblies into memory and everything is OK after.
So I added this to my script:
# SQL cmdlets below need some dll imports from system
# These do not get loaded sometime when running under an non-admin account (Cannof find a provider with the name 'SqlServer')
# Running this dummy command seems to load all needed dlls
# Also see: https://www.sqlservercentral.com/forums/topic/unable-access-sql-provider-in-powershell-without-running-an-invoke-sqlcmd-first
Invoke-Sqlcmd | Out-Null
Seems like valuable information that shouldn't get lost, so I thought i'd post it in the highest SO when googling for that particular error.
One could argue that installing the module rather than this dummy method would be cleaner.

As pointed, here are the links that you should refer now.
MSDN Link
Running SQL Server Powershell
Cannot find path 'SQLSERVER' Issue
There is an answer given by Jarret. Simply loading the module won't help actually. These set of commands have to run after that.
Push-Location
cd $sqlpsPath
Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
Update-TypeData -PrependPath SQLProvider.Types.ps1xml
update-FormatData -prependpath SQLProvider.Format.ps1xml
Pop-Location
Hope it helps.

Related

PowerShell v5.1 - Loading SqlServer Module does not load Read-SqlTableData or Write-SqlTableData, but Loads All Other Commands

On my Windows Server 2012 R2 server, the same server as my SQL Server service instance is running, I had upgraded to PowerShell v5.1. I proceeded to load the SqlServer module v21.1.18121. All commands loaded fine except for Read-SqlTableData and Write-SqlTableData. The darndest thing! When I load the same SqlServer module on my Win10 development box, all commands are present. I suspect something like a version problem with the available .Net framework or some such, or a collision with SQL Server's modules. Anyone with thoughts on this one?
The SqlServer module comes with the SQL Server installation and thems to be in a different version.
Module location on a SQL Server
(Get-Module -l SqlServer).path
-> C:\Program Files\WindowsPowerShell\Modules\SqlServer\SqlServer.psd1
Module location from PowerSehll gallery
(Get-Module -l SqlServer).path
-> C:\Program Files\WindowsPowerShell\Modules\SqlServer\21.0.17279\SqlServer.psd1
You can enforce PowerSell to load a module from specific location
Install-Module -Name SqlServer
Import-Module -Name (Get-Module -l SqlServer).path -Verbose
I've just encountered the same problem. I've tried many things, but I think the problem stems from having the module SQLPS installed alongside SqlServer module. (SQLPS being an older version of sqlserver).
The steps I used: (probably a little excessive)
Close every application that may have a reference to Powershell
modules. For me this list included Visual Studio, SSMS, SQL Agent,
and of course all Powershell cmd and/or IDE.
Open a Administrator PowerShell command shell.
execute:
Uninstall-Module sqlps
Uninstall-Module sqlserver
Check the Powershell modules folder to make sure you've cleared the modules.
The place to look is:
ls "c:\program files\WindowsPowerShell\Modules"
Both of the folders "sqlps" and "sqlserver" should be missing or empty.
Now re-install sqlserver module:
Install-Module sqlserver
Check that you have the Write-SqlTableData:
Get-Command -module sqlserver
In case you suspect you have an error with versioning: I have tried and tested sqlserver module versions: 21.1.18218 & 21.0.17099

Xp_CmdShell Powershell Script No Valid Module Found

I'm trying to run a PS1 file in T-SQL using XP_CMDSHELL, like so:
exec xp_cmdshell 'powershell -ExecutionPolicy bypass -command "C:\Users\sleven\Documents\DimAcctImport.ps1"'
The powershell script is as follows:
import-module dbatools
Import-DbaCsv -SqlInstance 'MSSQL' -Database 'Test' -Table 'Account' -Path "R:\Data\Account.csv" -Delimiter ',' -Quote '"' -KeepNulls -NoProgress
This script uses the cmdlet Import-DbaCSV of module DbaTools to import the CSV to the target table.
Here is the error I receive in SSMS:
import-module : The specified module 'dbatools' was not loaded because no valid module file was found in any module
directory.
At C:\Users\sleven\Documents\DimAcctImport.ps1:1 char:1
+ import-module dbatools
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (dbatools:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
The module is installed and runs as expected if I copy the PowerShell script and run it in PS ISE.
I'm using SQL Developer Edition on the same PC as I'm using to run the sp - my local PC.
What am I missing?
EDIT: Adding output from get-module and $PSVersionTable
PS> (Get-Module -ListAvailable dbatools).Path:
C:\Users\sleven\Documents\WindowsPowerShell\Modules\dbatools\0.9.834\dbatools.psd1
PS> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.18362.145
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.145
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Using Import-Module cmdlet tells PowerShell to look for cmdlet only in certain folders. You can check these folders by checking environment variable PSModulePath (splitting added for better visibility):
$env:PSModulePath -split ';'
In that case, when running PowerShell by xp_cmdshell, that folder is not included in PSModulePath (might happen as well if you use different account as your module is currently in your profile folder). Now you have two options:
Reference the module using its path, not name. You can get path using (get-module -ListAvailable dbatools).path:
# Replace the path with the path you found with Get-Module
Import-Module 'C:\path\to\module\dbatools.psd1
Modify your $env:PSModulePath. As that topic is more broader, let me give you the link to the docs. Remember that you should set that variable for the user running xp_cmdshell. As RThomas mentioned, by default it's not your user account. See linked answer for explanation on that topic.
NOTE (credits go to #David Browne - Microsoft from his comments):
If you're going to set the environment variable, it should be a system environment variable, as you wouldn't want this process to break if you change the SQL Server service account. And remember, setting a system environment variable requires a reboot for services to see the change.
It's likely an account issue. Keep in mind that running xp_cmdshell by default runs everything as the service account behind the SQL Server instance. So you'll want to verify what account this is.
If it's a built in system account this can cause strange behavior when it comes to rights.
If it's a windows or a domain account then you'll want to test externally to SQL Server by running the PS file not as yourself but as the same account SQL Server uses as a service account. You can do this easily by opening the cmd shell with shift/right click and specifying the other account.
Your other option is to set up a proxy account for the xp_cmdshell call to use. Instructions on how to do this can be found in Microsoft documentation.

Import-Module : The specified module 'SqlServer' was not loaded because no valid module file was found in any module directory

Well, hello there!
I'm working on a Script to get the Sql Job History and need to use the "SqlServer" Module. It's installed but I can't import it due to the Error Message above. When I got to the Modules Path, the Folder "SqlServer" exists and isn't empty. Don't get the problem here.
Thanks in advance!
I just ran into this on SQL Server 2017 (on Windows Server 2016) and found your question in the process. I then went and fired up our older SQL Server 2014 (Windows Server 2012) machine and found the same issue. Here's a couple options everyone can try to save some time (as I realize the question is kind of old and I'm assuming the OP found a solution already):
1) At a powershell command run: Install-Module -Name SqlServer (you might need -AllowClobber parameter)
The thing here is that module is installed to the following path on both 2012 and 2016 servers:
C:\Program Files\WindowsPowerShell\Modules\SqlServer (rather than Microsoft SQL
Server\120\Tools\PowerShell\Modules)
2) Another option is to try the SQLPS module by changing in your script:
Import-Module -Name SqlServer
To:
Import-Module -Name SQLPS
You will find SQLPS in the Microsoft SQL Server directory structure here:
C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules
My script works with both SQL modules now, but the output actually looks better with SQLPS at this point...
You can find more on all of the above at this link
With TLS v1.0 and v1.1 being deprecated on Microsoft Services services in 2022/Q2, this error comes up again on non-updated Windows and/or PS versions.
The issue is solved by forcing PS to use TLS v1.2 and an updated NuGet version ...
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -RequiredVersion 2.8.5.201 -Force
... before running Import-Module -Name SqlServer.
As pointed out at this related question in DBA/StackExchange.

SQL Powershell Error: Invoke-Sqlcmd : The term 'Invoke-Sqlcmd' is not recognized as the name of a cmdlet

When I try to run a powershell script I get the following error:
Invoke-Sqlcmd : The term 'Invoke-Sqlcmd' is not recognized as the name of a cmdlet, function, script file, or operable program.
So in Powershell I ran the following:
install-module sqlserver
update-module sqlserver
import-module sqlserver
This all runs fine. However when I rerun my script I still get the same error.
I have also installed powershelltools.msi, downloaded as part of the SQL Server 2014 Feature pack here: https://www.microsoft.com/en-gb/download/details.aspx?id=42295
If I run this command:
Get-Command -Module sqlserver
I get this result:
CommandType Name Version Source
----------- ---- ------- ------
Alias Decode-SqlName 21.0.17224 sqlserver
Alias Encode-SqlName 21.0.17224 sqlserver
Function SQLSERVER: 21.0.17224 sqlserver
Any ideas on what else I should try?
I have SQLServer 2014 and Powershell Version 5
Are you using Powershell Core (v6.1)?
I was having a similar issue and found this SO answer. Turns out the SQLServer module for Powershell Core doesn't include the Invoke-SqlCmd (among others). I switched back to the 64-bit version of Powershell I have installed on Windows 10 (v5.1) and installed, then imported the sqlserver module. Invoke-SQLCmd is now listed.
Install-Module -Name SqlServer -AllowClobber
Import-Module -Name SqlServer -Force
Get-Command -Module SqlServer
Import-Module imports a module only to current powershell session, not globally. Add the import to your script or to profile.
Was searching a solution for the same problem and found the below worked for me.
find-module sqlserver | Install-Module -AllowClobber -Force
Original Answer: https://social.technet.microsoft.com/Forums/en-US/f3a52235-e62a-402e-9b1b-0b0c0cdd17aa/sql-powershell-error-invokesqlcmd-the-term-invokesqlcmd-is-not-recognized-as-the-name-of-a?forum=winserverpowershell
I had the same problem. Apparently I had to unblock all the dll files in the new module folder. In my case C:\Program Files\WindowsPowerShell\Modules\SqlServer.
I found the link here how to do it.
https://www.404techsupport.com/2016/06/24/unblock-files-powershell/
dir -Path [directory path] -Recurse | Unblock-File
Close powershell if you still have a session open.

How to Acess Remote Computer Folders in PS SQLSERVER:\>

Recently I came to know how to use Powersehll commands for executing SQL queries as mentioned below:
Import-Module “sqlps” -DisableNameChecking
$ds=Invoke-Sqlcmd -Query $Query -Database $Database -ServerInstance $server -ConnectionTimeout $ConnectionTimeout -QueryTimeout $QueryTimeout
At this time Powershell ISE output Console will be in
PS SQLSERVER:\>
I was able to perform Select and Update queries without any error. The problem is faced when I wanted to access one of the file in remote computer. I tried to access the file as below:
PS SQLSERVER:\> Get-Content -Path \\Server\D$\Log\App.log
Even tried, just to list files/folders as
PS SQLSERVER:\> ls \\Server\D$\Log\
Iam getting below errors:
Get-Content : Cannot find path '\Server\D$\Log\App.log' because it does not exist.
ls : Cannot find path '\Server\D$\Log\' because it does not exist.
Need not to say- folder and file exists on that server as I was able to access the same when Powershell is running without SQL module. I mean console was showing just
PS C:\User\abc\
Sorry for this long story-- now, simple question!
How to access remote files/folders when Shell is in SQLSERVER console?
Thanks in Advance!
-Raj
You should be able to use the filesystem provider explicitly like this:
ls filesystem::\\server\d$\log
Just change your directory like so:
cd c:\
then:
ls \\server\d$\log
you can then change back to sql server by doing the same:
cd sqlserver:\
The powershell providers can be used just like you would a normal drive letter, pretty cool.
I believe it's running the commands remotely on the SQL server, which makes accessing data on another server from there a "double hop" scenario, and you'll need CredSSP auth for that to work.....

Resources