PowerShell :: SQL SELECT returns 只有第一行
PowerShell :: SQL SELECT returns only first row
我有一种奇怪的感觉,我做错了什么。
这是我的 PowerShell 脚本,当然是从 here:
中盗取和改编的
param(
$instance = "localhost"
)
if (!(Get-Module -ListAvailable -Name "SQLPS")) {
Write-Host -BackgroundColor Red -ForegroundColor White "Module Invoke-Sqlcmd is not loaded"
exit
}
#Function to execute queries (depending on if the user will be using specific credentials or not)
function Execute-Query([string]$query,[string]$database,[string]$instance,[int]$trusted,[string]$username,[string]$password){
if($trusted -eq 1){
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
else{
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -Username $username -Password $password -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
}
function List-of-Databases([string]$instance,[int]$trusted,[string]$login,[string]$password){
$ctpQuery = "
SELECT name
FROM master.dbo.sysdatabases
"
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
}
function Check-SysAdminLogins([string]$instance,[int]$trusted,[string]$login,[string]$password){
$sysadminLoginsQuery = "
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
"
return $(Execute-Query $sysadminLoginsQuery "master" $instance $trusted $login $password)
}
$loginChoices = [System.Management.Automation.Host.ChoiceDescription[]] @("&Trusted", "&Windows Login", "&SQL Login")
$loginChoice = $host.UI.PromptForChoice('', 'Choose login type for instance', $loginChoices, 0)
switch($loginChoice)
{
1 {
$login = Read-Host -Prompt "Enter Windows Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
2 {
$login = Read-Host -Prompt "Enter SQL Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
}
#Attempt to connect to the SQL Server instance using the information provided by the user
try{
switch($loginChoice){
0 {$buildNumber = Execute-Query "SELECT 1" "master" $instance 1 "" ""}
default {$buildNumber = Execute-Query "SELECT 1" "master" $instance 0 $login $password}
}
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
#If the connection succeeds, then proceed with the verification of best practices
Write-Host ""
Write-Host "------------ ------------ ------------ ------------"
Write-Host "************ ************ ************ ************"
Write-Host "------------ ---- ---- ------------"
Write-Host " **** ************ ************ **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** **** ***** **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** ************ ************ **** "
Write-Host ""
#List of Databases
Write-Host "#####################"
Write-Host "# List of Databases #"
Write-Host "#####################"
switch($loginChoice){
0 {$lod = List-of-Databases $instance 1 "" ""}
default {$lod = List-of-Databases $instance 0 $login $password}
}
foreach($database in $lod)
{
Write-Host $database.name | Format-Table
}
Write-Host ""
#Logins with sysadmin privilege
Write-Host "##################################"
Write-Host "# Logins with sysadmin privilege #"
Write-Host "##################################"
switch($loginChoice){
0 {$sysadminLogins = Check-SysadminLogins $instance 1 "" ""}
default {$sysadminLogins = Check-SysadminLogins $instance 0 $login $password}
}
foreach($sysadminLogin in $sysadminLogins)
{
Write-Host $sysadminLogin.name
}
Write-Host ""
如果你 运行 脚本成功执行:
问题是第二个查询:
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
正确returns 所有行:
##################################
# Logins with sysadmin privilege #
##################################
NT SERVICE\SQLSERVERAGENT
NT SERVICE\SQLWriter
NT SERVICE\Winmgmt
sa
而第一个查询:
SELECT name
FROM master.dbo.sysdatabases
只有returns第一行SELECT语句,当然master数据库:
#####################
# List of Databases #
#####################
master
但是如您所见,我里面有很多数据库。
我哪里错了?
注意return
语句末尾的数组索引:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
那将 return 只有第一行。尝试:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)
我有一种奇怪的感觉,我做错了什么。
这是我的 PowerShell 脚本,当然是从 here:
中盗取和改编的param(
$instance = "localhost"
)
if (!(Get-Module -ListAvailable -Name "SQLPS")) {
Write-Host -BackgroundColor Red -ForegroundColor White "Module Invoke-Sqlcmd is not loaded"
exit
}
#Function to execute queries (depending on if the user will be using specific credentials or not)
function Execute-Query([string]$query,[string]$database,[string]$instance,[int]$trusted,[string]$username,[string]$password){
if($trusted -eq 1){
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
else{
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -Username $username -Password $password -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
}
function List-of-Databases([string]$instance,[int]$trusted,[string]$login,[string]$password){
$ctpQuery = "
SELECT name
FROM master.dbo.sysdatabases
"
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
}
function Check-SysAdminLogins([string]$instance,[int]$trusted,[string]$login,[string]$password){
$sysadminLoginsQuery = "
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
"
return $(Execute-Query $sysadminLoginsQuery "master" $instance $trusted $login $password)
}
$loginChoices = [System.Management.Automation.Host.ChoiceDescription[]] @("&Trusted", "&Windows Login", "&SQL Login")
$loginChoice = $host.UI.PromptForChoice('', 'Choose login type for instance', $loginChoices, 0)
switch($loginChoice)
{
1 {
$login = Read-Host -Prompt "Enter Windows Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
2 {
$login = Read-Host -Prompt "Enter SQL Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
}
#Attempt to connect to the SQL Server instance using the information provided by the user
try{
switch($loginChoice){
0 {$buildNumber = Execute-Query "SELECT 1" "master" $instance 1 "" ""}
default {$buildNumber = Execute-Query "SELECT 1" "master" $instance 0 $login $password}
}
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
#If the connection succeeds, then proceed with the verification of best practices
Write-Host ""
Write-Host "------------ ------------ ------------ ------------"
Write-Host "************ ************ ************ ************"
Write-Host "------------ ---- ---- ------------"
Write-Host " **** ************ ************ **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** **** ***** **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** ************ ************ **** "
Write-Host ""
#List of Databases
Write-Host "#####################"
Write-Host "# List of Databases #"
Write-Host "#####################"
switch($loginChoice){
0 {$lod = List-of-Databases $instance 1 "" ""}
default {$lod = List-of-Databases $instance 0 $login $password}
}
foreach($database in $lod)
{
Write-Host $database.name | Format-Table
}
Write-Host ""
#Logins with sysadmin privilege
Write-Host "##################################"
Write-Host "# Logins with sysadmin privilege #"
Write-Host "##################################"
switch($loginChoice){
0 {$sysadminLogins = Check-SysadminLogins $instance 1 "" ""}
default {$sysadminLogins = Check-SysadminLogins $instance 0 $login $password}
}
foreach($sysadminLogin in $sysadminLogins)
{
Write-Host $sysadminLogin.name
}
Write-Host ""
如果你 运行 脚本成功执行:
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
正确returns 所有行:
##################################
# Logins with sysadmin privilege #
##################################
NT SERVICE\SQLSERVERAGENT
NT SERVICE\SQLWriter
NT SERVICE\Winmgmt
sa
而第一个查询:
SELECT name
FROM master.dbo.sysdatabases
只有returns第一行SELECT语句,当然master数据库:
#####################
# List of Databases #
#####################
master
但是如您所见,我里面有很多数据库。
我哪里错了?
注意return
语句末尾的数组索引:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
那将 return 只有第一行。尝试:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)