问题
I'm querying Active Directory with a string which loops through each domain controller in our system and returns a set of results. The script works great with export-csv but because we wish to retain all data in the custom info field (it contains carriage-returns) I'd like to export this directly into an SQL table.
The error reported by Powershell reads:
Exception calling "ExecuteNonQuery" with "0" argument(s): "Insert Error: Column name or >number of supplied values does not match table definition."
Which is a pretty verbose response, I've created and named the columns of each table to exactly match the output of the get-object.
Here's the output from the pipe:
SamAccountName : testuser
DisplayName : Test User (COMPANY)
info : Test Entry 1234567890
Test for output.
Entering
Multiple lines.
whenCreated : 09/11/2004 09:08:42
whenChanged : 19/07/2012 09:25:21
AccountExpires :
pwdLastSet : 13/06/2012 07:43:43
LastLogonTimestamp : 18/07/2012 15:38:35
userAccountControl : 512
Name : Test User
LastLogon :
DC : DCNAME1
And here's the code:
##--AD data output to SQL script, you need the Quest plugin!
$SamAccountName = Read-Host "Enter the username to query for last logon"
##--Query domain for all domain controllers and funnel into a forEach loop
Get-QADComputer -ComputerRole DomainController | Foreach-Object{
$dc = $_.Name
##--Query each domain controller for the user object and retrieve the LastLogon timestamp
$user = Get-QADUser -Service $dc -SamAccountName $SamAccountName -IncludedProperties info,pwdLastSet,AccountExpires,userAccountControl | Select-Object SamAccountName,displayName,info,whenCreated,whenChanged,accountExpires,pwdLastSet,lastLogonTimestamp,userAccountControl,name,LastLogon,@{n='DC';e={$dc}} |
out-host
##--Open database connection
$conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=SQLSERVER; Initial Catalog=ADomain; Integrated Security=SSPI")
$conn.Open()
##--AAGH! How to grab the results of the Select-Object above?
$cmd = $conn.CreateCommand()
$cmd.CommandText ="INSERT extract VALUES ('$user')"
$cmd.ExecuteNonQuery()
##--Don't forget to close it!
$conn.Close()
Now I'm messing something up which is probably plainly obvious, any help much appreciated.
回答1:
Assume the following test object:
$exampleObject = New-Object PSObject -Property @{SamAccountName="TestSAN";DisplayName="TestDN"}
$user = $exampleObject | Select-Object SamAccountName, DisplayName
##--AAGH! How to grab the results of the Select-Object above?
$commandText = "INSERT extract VALUES ('$($user.SamAccountName)','$($user.DisplayName)'"
I would also move the sql connect and close to outside of a loop and place it in a try/finally block, so it is only done once instead of for each DC entry and the Close is still called when there is an Exception during the execution of the try block. See here for reference on using a try/catch/finally block with Powershell.
回答2:
here I'm using SqlServerCmdletSnapin and it's Invoke-sqlcmd. This script is using MSSQL database EMPLOYEE and table EMPLOYEE_DOMAIN. Hope it helps. Works fine for me..
Add-PSSnapin Quest.ActiveRoles.ADManagement
Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
$db_server = "10.3.18.55"
$db = "EMPLOYEE"
$table = "EMPLOYEE_DOMAIN"
$username = "import"
$pwd = "Okinawa84561"
# First, clear existing table
$sql_query_del = "DELETE FROM $table"
Invoke-Sqlcmd -ServerInstance $db_server -Database $db -Username $username -Password $pwd -Query $sql_query_del
# Get users with employeeID only and write their accountname and employeeID to DB
Get-QADUser -IncludeAllProperties | ? {$_.employeeID} | select sAMAccountName, employeeID | foreach {
$an = $_.sAMAccountName
$eid = $_.employeeID
Write-Host " sAMAccountName : $an employeeID : $eid"
$sql_query = "INSERT INTO $table (employeeID, domainName) VALUES ('$eid', '$an')"
Invoke-Sqlcmd -ServerInstance $db_server -Database $db -Username $username -Password $pwd -Query $sql_query
}
来源:https://stackoverflow.com/questions/11647305/powershell-get-qaduser-results-to-sql-table