I have this PowerShell script:
$QUERY = "SELECT name FROM sys.databases";
$Databases = invoke-sqlcmd -serverinstance "SQLInstanceName" -database "master" -Query $QUERY
foreach ($dbname in $Databases)
{
$dbname
}
Let's say I want the recovery model for the databases as below, how do I get them into PowerShell variables?
$QUERY = "SELECT name, recovery_model_desc FROM sys.databases";
May be you are looking for
$QUERY = "SELECT * from sys.databases";
$Databases = invoke-sqlcmd -serverinstance "SQLInstanceName" -database "master" -Query $QUERY
# This is just to print the individual value of column (name and recovery_model)
$Databases | ForEach {
Write-Host '----------------------------------------'
Write-Host 'Database :' $_.name
Write-Host 'Recovery model :' $_.recovery_model
Write-Host '----------------------------------------'
Write-Host
}
# This will give you name and recovery_model of database
$Databases | Select name, recovery_model
Related
I'm attempting to use a result returned from Invoke-Sqlcmd $ORDUNIQ as a variable in a second query. However the second $query2 returns 0 records. Substituting the variable for the actual string value '35973189' works fine.
I'm assuming that $ORDUNIQ.ORDUNIQ is the wrong way to use this?, although running $ORDUNIQ.ORDUNIQ on the command line does return '35973189' correctly
Here is my code
$RAWFiles = Get-ChildItem D:\Imports\Test\*.csv
$content = Import-Csv $RAWFiles | Where-Object 'Order Type' -eq 'B2B'
ForEach ($row in $content) {
$ORDNUMBER = $row.'OrderRef'
$SQLServer = "XXXXX-XXX"
$db1 = "XXXXXX"
$query1 = "SELECT ORDUNIQ FROM OEORDH WHERE ORDNUMBER = '$ORDNUMBER'"
$query2 = "SELECT OEORDD.ITEM FROM OEORDD WHERE ORDUNIQ = '$ORDUNIQ.ORDUNIQ'"
$ORDUNIQ = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db1 -Query $query1
$ORDDATA = Invoke-SQLcmd -ServerInstance $SQLServer -Database $db1 -Query $query2
}
Good morning everyone. I am currently in school, working on a PowerShell project, part 2. I was able to get the script to work but now I'm being asked to do this, Check for the existence of a database named ClientDB. Output a message to the console that indicates if the database exists or if it does not. If it already exists, delete it and output a message to the console that it was deleted.Create a new database named “ClientDB” on the Microsoft SQL server instance. Output a message to the console that the database was created. Then go through the rest in creating the table and importing the csv as I've done that much. My problem is how to use the invoke-sqlcmd in an if/else, else/if statement. Thank you so much.
Try {
$DBname = "ClientDB"
$SqlServer = ".\SQLEXPRESS"
if([bool] (Get-SQLDatabase -Filter * | ? {$SqlServer -eq $DBname} ))
{ Write-Host 'ClientDB exists' }
else { Write-Host 'ClientDB does not exists' }
$CreateTableQuery = #"
use $DBname
CREATE TABLE Client_A_Contacts
(
first_name varchar(20),
last_name varchar(20),
city varchar(20),
county varchar(20),
zip varchar(20),
officePhone varchar(20),
mobilePhone varchar(20)
)
"#
Import-Module sqlps -DisableNameChecking
$ServerObject = New-Object Microsoft.SqlServer.Management.Smo.Server($SqlServer)
$DBobject = New-Object Microsoft.SqlServer.Management.Smo.Database($ServerObject, $DBname)
$DBobject.Create()
Write-Host $DBobject "create success # " $DBobject.CreateDate
Invoke-sqlcmd -ServerInstance $SqlServer -Database $DBname -Query $CreateTableQuery
Pop-Location
Import-Csv "NewClientData.csv" | ForEach-Object {Invoke-sqlcmd -ServerInstance $SqlServer -
Database $DBname -Query "insert into dbo.Client_A_Contacts values
('$($_.first_name)','$($_.last_name)','$($_.city)','$($_.county)',
'$($_.zip)','$($_.officePhone)','$($ _.mobilePhone)')"}
}
catch [System.OutOfMemoryException] {
Write-Host "Caught: System.OutOfMemoryException"
}
Invoke-Sqlcmd -Database ClientDB –ServerInstance .\SQLEXPRESS -Query ‘SELECT * FROM dbo.Client_A_Contacts’ > .\SqlResults.txt
I'm trying to run a sql query via PowerShell and return the results in a table-like format.
It's putting multiple results in one field. I suspect there's something wrong with the 'foreach' loops. What am I missing, please?
To use the code below, just change the server names from 'server1'/'server2' for your sql server instances.
$query = "
SELECT ##SERVERNAME AS ServerName
, (SELECT DB_NAME ()) AS DBName
, s.name AS SchemaName
, st.name AS TableName
, RIGHT(st.name, 8) AS Rgt8
, TRY_CONVERT(DATE, RIGHT(st.name, 8), 103) AS Rgt8Date
FROM sys.tables AS st
INNER JOIN sys.objects AS so ON so.object_id = st.object_id
INNER JOIN sys.schemas AS s ON s.schema_id = st.schema_id
"
$instanceNameList = #('server1', 'server2')
$report = #()
foreach ($instanceName in $instanceNameList) {
write-host "Executing query against SERVER/INSTANCE: " $instanceName
$dbNames = Invoke-DbaQuery -SqlInstance $InstanceName -Database "master" -Query "select name from sys.databases where database_id > 4 and name <> 'TEST'"
foreach ($database in $dbNames.Name ) {
Write-host -Activity "Current DATABASE $database" -Status "Querying: $database"
$results = Invoke-DbaQuery -SqlInstance $InstanceName -Database $database -Query $query
# <#
if ($results -is [array]) {
$CustomObject = [pscustomobject] #{
ServerName = $results.ServerName
DBName = $results.DBName
SchemaName = $results.SchemaName
TableName = $results.TableName
Rgt8 = $results.Rgt8
Rgt8Date = $results.Rgt8Date
OverOneYearOld = $results.OverOneYearOld
Drop_Table = $results.Drop_Table
}
## ADDING EACH ROW/JOB OBJECT THAT HAS BEEN REPORTED, TO THE REPORT ARRAY
$report += $CustomObject
}
}
}
$report | Select-Object ServerName, DbName, TableName | Out-GridView
Basically, you're doing the opposite of what you wanted to do, if $results -is [array] you want to iterate over it instead of add it as is to to your $report array.
On the other hand, adding elements to a fixed collection (+=) is a terrible idea.
$dbquery = #'
select name from
sys.databases
where database_id > 4 and name <> 'TEST'"
'#
$result = foreach ($instanceName in $instanceNameList) {
$params = #{
SqlInstance = $InstanceName
Database = "master"
Query = $dbquery
}
$dbNames = Invoke-DbaQuery #params
foreach ($database in $dbNames.Name) {
$params.Database = $database
$params.Query = $query
Invoke-DbaQuery #params | Select-Object #(
'ServerName'
'DBName'
'SchemaName'
'TableName'
'Rgt8'
'Rgt8Date'
'OverOneYearOld'
'Drop_Table'
)
}
}
$result | Format-Table
I have an array that loops through a string assigning values to elements. If I then assign those elements to a variable and pass that variable into the invoke-sqlcmd I get an error. However, if I assign the value directly to the variable and pass it in it works fine:
Assign value to array:
for ($i=0; $i -lt $somearray.length; $i++) {
$somearray[$i] = $somearray[$i].Replace('$(query)', $query.text)
}
Lets say somearray[0] = "select * from DB". We'll assign to a variable:
$query = somearray[0]
Now I pass this to my Invoke-Sqlcmd:
Invoke-Sqlcmd -Query $query -Database "local" -ServerInstance "somedb" |
Export-Csv ".\somefile.csv"
This fails:
Invoke-Sqlcmd : Could not find stored procedure 'select * from ALERTS'.
At C:\Migration\ExportTool\ExportTool\Gavs.ps1:95 char:17
+ ... Invoke-Sqlcmd -Query $query -Database $db -ServerInstance ...
However, if I do this:
$query = "select * from DB"
Invoke-Sqlcmd -Query $query -Database "local" -ServerInstance "somedb" |
Export-Csv ".\somefile.csv"
it works perfectly.
So the reason appears to be, if you do this:
$query = somearray[0]
When you view $query in the Invoke-sql command it looks like this:
"select * from DB"
And when you do this:
$query = "select * from DB"
It looks like this:
select * from DB
So directly referencing a string removes the quotes in the Invoke-sqlcmd command. Seems very odd.
Hope this helps someone in the future.
As you can see, the variable $SQLRCNumberNew is inside another variable $SQLUpdateRC which has been declared before $SQLRCNumberNew did.
When I am running the script $SQLRCNumberNew is empty, which makes sense because it is declared inside $SQLUpdateRC at the beginning.
What I want to ask if someone has an idea how I can update $SQLRCNumberNew even it is declared at the beginning.
I know I can just put the string Variable right below, but this is not what I am looking for.
Thanks for any help!
$RCFirstDigit = 0
$RCSecondDigit = 0
$PhoenixDBServer = "Servername"
$PhoenixDBName = "Databasename"
$ProductionDBServer = "Servername"
$ProductionDBName = "Databasename"
$SQLSelectRC = $("SELECT [Char_Value_01] FROM [dbo].[TABLENAME] WHERE [Keyword] = 'Version Number'")
$SQLUpdateRC = $("UPDATE TABLENAME set Char_Value_01 = '$SQLRCNumberNew' where Keyword = 'Version Number'")
Switch ($env:COMPUTERNAME) {
$PhoenixDBServer {
$Server = $PhoenixDBServer + "." + $env:USERDNSDOMAIN
$Database = $PhoenixDBName
}
$ProductionDBServer {
$Server = $ProductionDBServer + "." + $env:USERDNSDOMAIN
$Database = $ProductionDBName
}
default {
Write-Verbose "This script does not run on this computer"
exit
}
}
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
[int]$RCFirstDigit = $SQLRCNumber.Char_Value_01.split(".")[1]
[int]$RCSecondDigit = $SQLRCNumber.Char_Value_01.split(".")[2]
$RCSecondDigit++
# put string back together with updated RC number
[string]$SQLRCNumberNew = $SQLRCNumber.Char_Value_01.Split(".")[0] + "." + $RCFirstDigit + "." + $RCSecondDigit
# Update RC Version on Database
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC
Just to be clear - this is not how PowerShell scripting works. When you assign data to your variables, at least when working with strings.
You could have a function inside your script file, that you could call and have it return the concatenated string.
Function StringBuilder {
Param ($Value)
"UPDATE TABLENAME set Char_Value_01 = '$Value' where Keyword = 'Version Number'"
}
...
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
$SQLUpdateRC = StringBuild $SQLRCNumber
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC
...
Something like that should work. But I would say you should have a string format defined in the top and simply format when you need it.
$SQLUpdateRCBase = "UPDATE TABLENAME set Char_Value_01 = '{0}' where Keyword = 'Version Number'"
...
$SQLRCNumber = Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLSelectRC
$SQLUpdateRC = $SQLUpdateRCBase -f $SQLRCNumber
Invoke-Sqlcmd -ServerInstance $Server -Database $Database -Query $SQLUpdateRC