0

我有以下从 VB 脚本转换而来的 powershell 命令:

$conn = New-Object System.Data.SqlClient.SqlConnection(“Data Source=SERVER; Initial Catalog=DATABASE; Integrated Security=SSPI”) 
$conn.Open() 
$cmd1 = $conn.CreateCommand() 
$cmd1.CommandType = [System.Data.CommandType]::Text 
$cmd1.CommandText =“SELECT guid, name, [Serial Number] FROM dbo.wrksta as a inner join Inv_AeX_HW_Serial_Number as b on a.GUID=b._resourceGUID ORDER BY Name” 
$data = $cmd1.ExecuteReader() 
$cmd2 = $conn.CreateCommand() 
$cmd2.CommandType = [System.Data.CommandType]::Text 
$cmd2.CommandText =“SELECT top 1 [User] FROM dbo.Evt_aex_client_logon WHERE _resourceGuid = (SELECT top 1 Guid FROM dbo.Wrksta WHERE Name='" + $data["name"] + "' ORDER BY WrkstaID DESC) AND Event = 'logon' AND _eventTime > getdate()-60 GROUP BY [User] ORDER BY count([User]) desc” 
$data2 = $cmd2.ExecuteReader() 
$dt = new-object “System.Data.DataTable” 
$dt.Load($data2) 
$dt | format-table 
$conn.Close() 

如果您查看第二个 select 语句,我想使用第一个变量 $data 中的值,但我不确定如何编写它。在 VB 中就像这样 WHERE Name='" + Workstation("name").value + "' 以下是在 powershell 中编写此代码的正确方法吗?'" + $数据["名称"] + "'。我在 $date 变量中存储的名称列中的值之后

以前用来做这个的VB如下

connString = "Provider=sqloledb;Data Source=SERVER;Initial Catalog=DATABASE;Integrated Security=SSPI;"
objSQL.Open connString 

sqlWorkstations = "SELECT guid, name, [Serial Number] FROM dbo.wrksta as a inner join Inv_AeX_HW_Serial_Number as b on a.GUID=b._resourceGUID ORDER BY Name"
Set workstation = objSQL.Execute(sqlWorkstations)

Do Until (workstation.EOF)

sqlUser = "SELECT top 1 [User] FROM dbo.Evt_aex_client_logon WHERE _resourceGuid = (SELECT top 1 Guid FROM dbo.Wrksta WHERE Name='" + workstation("name").value + "' ORDER BY WrkstaID DESC) AND Event = 'logon' AND _eventTime > getdate()-60 GROUP BY [User] ORDER BY count([User]) desc"
set user = objSQL.Execute(sqlUser)

if not user.eof then
  userName = user("User").value
else
  username = "??????"
end if
4

2 回答 2

2

让您自己更轻松并加载SqlServerCmdletSnapin100管理单元。如果您使用的是 SQL Server,它会为您处理大部分样板文件,并将正在运行的查询提炼为单个 cmdlet。

您上面的代码假定第一个查询仅返回一行。这可能会也可能不会总是如此;我不知道你的数据库。如果它返回多条记录,那么您的代码只会为您提供与第一个查询中的第一条记录相对应的数据。

使用SqlServerCmdletSnapin100'sInvoke-SQLCmd并处理返回多条记录的情况,请执行以下操作:

$data1 = Invoke-Sqlcmd -ServerInstance SERVER -Database DATABASE -Query “SELECT guid, name, [Serial Number] FROM dbo.wrksta as a inner join Inv_AeX_HW_Serial_Number as b on a.GUID=b._resourceGUID ORDER BY Name”;
foreach ($row in $data1) {
    $name = $row.name;
    $data2 = invoke-sqlcmd -ServerInstance SERVER -Database DATABASE -Query “SELECT top 1 [User] FROM dbo.Evt_aex_client_logon WHERE _resourceGuid = (SELECT top 1 Guid FROM dbo.Wrksta WHERE Name='$name' ORDER BY WrkstaID DESC) AND Event = 'logon' AND _eventTime > getdate()-60 GROUP BY [User] ORDER BY count([User]) desc” ;
    $data2 |ft -AutoSize
}

也有可能您可以使用一个正确编写的查询来检索所有数据,但又一次,您不知道很难说的数据。您确实应该就这些查询咨询您的 DBA,以确保它们正确编写并正确匹配您的要求。

于 2012-09-07T12:59:58.760 回答
0

ExecuteReader只创建阅读器,但您需要调用 $data.Read() 来检索第一条记录。(请参阅链接的 MSDN 中的示例)

于 2012-09-07T13:00:07.637 回答