我正在尝试自动化一些查询,并正在查询sys.sql_logins,并在ssms和powershell中获得不同的查询结果。
我的疑问是:
$SQLquery =@"
Select 'sql_logins' [sql_logins], @@SERVERNAME [Hostname], DB_NAME() [Database], * from sys.sql_logins;
"@
当我从ssms中的查询中运行它时,SID结果为0xA1E3(一些长的字母数字字符串)。当我通过powershell运行相同的东西时,我得到了一个完全不同的SID格式。与长字母数字字符串不同,我最终得到的是{123、45、70、16},我不知道为什么或如何使它与ssms中的手动查询结果相匹配。
为什么会变呢?我如何使它不改变和保持像0xA1E3(超长字母数字字符串)?
编辑-按要求编辑
真的没有做任何特殊的事情来获取或显示数据。Invoke-sqlcmd
,然后在返回后吐出来。
$result = invoke-sqlcmd -query $SQLquery -serverinstance $computername -database $dbname -Username $dbuser -Password $dbpass
$result | Format-Table -Property Hostname, Database, name, principal_id, sid,`
type, type_desc, is_disabled, create_date, modify_date,`
default_database_name, default_language_name, credential_id,`
is_policy_checked, is_expiration_checked, password_hash -Autosize
发布于 2018-11-27 19:46:40
这个问题的另一个答案正确地识别了这个问题,因为从查询返回的varbinary被powershell视为一个字节数组。但是,我对修复的建议是不同的--更改查询中的格式。如果我将查询更改为:
Select 'sql_logins' [sql_logins],
@@SERVERNAME [Hostname],
DB_NAME() [Database],
convert(varchar(172), sid, 1) as sid
from sys.sql_logins;
然后在你剩下的代码中运行它,它对我有效。注意:我没有在我的查询中执行select *
--如果您确实需要所有的列,您应该显式地列出它们。最后,一个观察- sys.sql_logins
是服务器级的DMV;在每个数据库的基础上查询它对于同一服务器上的所有数据库都是重复的。
编辑-更改了varchar
的长度以适应varbinary(85)
SID,就像精细手册所说的。显示我的作品,(85个字节*2个字符/字节)+(‘0x’的2个字符)= 172。
发布于 2018-11-27 07:08:39
在SSMS的结果窗口上得到的SID是基于GUID的16字节(二进制(16))文字值,而在PowerShell中获得的SID正如注释中提到的那样,默认视图是用括号包围的逗号分隔的字节值列表。PowerShell比Server更擅长字符串操作,因此它在内部将二进制(16)值转换为字节值。
以下是你能做的-
$SQLquery = "Select 'sql_logins' [sql_logins], @@SERVERNAME [Hostname], DB_NAME() [Database], * from sys.sql_logins;"
$Result = Invoke-Sqlcmd -query $SQLquery -ServerInstance ServerName -Database master
$Result[0].sid
$Result[0].sid.Length
会给你1024,这意味着长度确实是一个KB。使用来自ConvertTo-SQLHashString
博客的迈克·法尔函数,其中他谈到通过PowerShell复制SQL登录-
function ConvertTo-SQLHashString{
param([parameter(Mandatory=$true)] $binhash)
$outstring = '0x'
$binhash | ForEach-Object {$outstring += ('{0:X}' -f $_).PadLeft(2, '0')}
return $outstring
}
ConvertTo-SQLHashString $Result[0].sid
这会给你一个很长的十六进制值。您可以使用PowerShell TrimEnd()
函数来获得类似于SSMS窗口中的结果-
(ConvertTo-SQLHashString $Result[0].sid).TrimEnd('0')
https://stackoverflow.com/questions/53493341
复制相似问题