sqlbulkcopycolumnmapping import csv to table issue - sql

I am at a loss. I am trying to import columns from a csv into an existing data table. I believe the best way to do this is through column mapping using sqlbulkcopy but i just cant wrap my head around this. Im using the script below with the out-datatable function to do column mapping and even though it appears to insert the data, when i run a query i cannot find it. What am i doing wrong?
import-module .\functions.psm1
# Database variables
$sqlserver = "Db-test-dev\sql2008"
$database = "Employees"
#$table = "dbo.tblPersonal"
$csvfile = "C:\temp\cidb_test.csv"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.connectionstring = "Data Source=$sqlserver;Integrated Security=true;Initial Catalog=$database;"
$CSVDataTable = Import-Csv ‘$csvfile’ | Out-DataTable
$sqlBulkCopy = New-Object (“Data.SqlClient.SqlBulkCopy”) -ArgumentList $SqlConnection
$sqlBulkCopy.DestinationTableName = “dbo.tblpersonal”
$ColumnMap1 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping(1, 1)
$ColumnMap2 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping(2, 2)
#$ColumnMap3 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping(2, 3)
$sqlBulkCopy.ColumnMappings.Add($ColumnMap1)
$sqlBulkCopy.ColumnMappings.Add($ColumnMap2)
#$sqlBulkCopy.ColumnMappings.Add($ColumnMap3)
$SqlConnection.Open()
$sqlBulkCopy.WriteToServer($CSVDataTable)
$SqlConnection.Close()

Added column mapping using bulkcopy
$ColumnMap1 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('SSN','SSN')
$ColumnMap2 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('LastName', 'LastName')
$ColumnMap3 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('MiddleName','MiddleName')
$ColumnMap4 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('FirstName','FirstName')
$ColumnMap5 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('PreferredName','PreferredName')
$ColumnMap6 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('WorkPhone','WorkPhone')
$ColumnMap7 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Email','Email')
$ColumnMap8 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('EmpType','EmpType')
$ColumnMap9 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('HireDate', 'HireDate')
$ColumnMap10 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('ACID','ACID')
$ColumnMap11 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('OPID','OPID')
$ColumnMap12 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Floor','Floor')
$ColumnMap13 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Department','Department')
$ColumnMap14 = New-Object System.Data.SqlClient.SqlBulkCopyColumnMapping('Division','Division')
$BulkCopy.ColumnMappings.Add($ColumnMap1)
$BulkCopy.ColumnMappings.Add($ColumnMap2)
$BulkCopy.ColumnMappings.Add($ColumnMap3)
$BulkCopy.ColumnMappings.Add($ColumnMap4)
$BulkCopy.ColumnMappings.Add($ColumnMap5)
$BulkCopy.ColumnMappings.Add($ColumnMap6)
$BulkCopy.ColumnMappings.Add($ColumnMap7)
$BulkCopy.ColumnMappings.Add($ColumnMap8)
$BulkCopy.ColumnMappings.Add($ColumnMap9)
$BulkCopy.ColumnMappings.Add($ColumnMap10)
$BulkCopy.ColumnMappings.Add($ColumnMap11)
$BulkCopy.ColumnMappings.Add($ColumnMap12)
$BulkCopy.ColumnMappings.Add($ColumnMap13)
$BulkCopy.ColumnMappings.Add($ColumnMap14)

Related

Extracting SQL values into powershell variables?

I currently have the following script:
$SQLServer = "sqldev1"
$SQLDBName = "SPDEV_Printing"
$SqlQuery = "select * from PcBeheerPrinter WHERE PRT_name = 'bwpsc006'"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
clear
$DataSet.Tables[0]
which returns some console output like this:
PRT_PrintServerName : pcounter
PRT_Name : bwpsc006
PRT_PortNameFull : PCOUNT_bwpsc006
PRT_CAL_SerialNumber :
PRT_ACTIVE : 1
PRT_CAL_RespondToPing : 1
PRT_CAL_NamePinged : bwpsc006
PRT_CAL_FirstSeendate : 8/02/2017 20:55:13
PRT_CAL_LastSeendate : 4/12/2017 11:36:19
PRT_CAL_SNMPPossible : 1
PRT_CAL_Brand :
PRT_ShareName : bwpsc006
PRT_Comment :
PRT_Datatype : RAW
PRT_DriverName : Canon iR-ADV C5045/5051 PCL6
PRT_Location :
PRT_PrintProcessor :
PRT_Published : 0
PRT_Shared : 0
PRT_NumberOfMissedPings : 0
PRT_LastResponsedate : 4/12/2017 11:36:19
PRT_RenderingMode : CSR
My question is: How do I transfer some of these values into PS variables?
I need the Name, SerialNumber and some others (these will do as example) to eventually transfer them to a SharePoint list.
I'm still a beginner and can't figure it out through googling.
Thanks!
When using the System.Data.SqlClient.SqlCommand class, most of the objects returned will be of type datatable. Since, $DataSet will be of type datatable, you can directly use all the returned properties like this -
$Name = $DataSet.Tables[0].PRT_Name;
$SerialNo = $DataSet.Tables[0].PRT_CAL_SerialNumber and so on.
You can then use the variables $Name and $Serialno as input to your SharePoint List.
If the data type is object, then you can directly use the select-object like:
$DataSet.Tables[0] | Select-object PRT_Name,PRT_CAL_SerialNumber

PowerShell SQL query using here-string and variable expansion

How can I combine the query results for servers that are swSaturday = 1 and swSunday = 1 The [RebootTime] could be swSunBeginTime or swSatBeginTime and it also might not help I'm only trying to run this query on a list of machines in a text file.
Error received is Exception calling "Fill" with "1" argument(s): "Incorrect syntax near the keyword 'WHERE'." and the error goes away if WHERE swName = $($props.Server) is removed.
Function GetServer-RebootLookUp{
Begin{
$servers = GC D:\Scripts\reboots1.txt
$SQLServer = 'Server101'
$Database = 'Database101'
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
}#End Begin
Process{
$servers | ForEach-Object{
$props = #{}
$props.Server = $_
$ServerQuery = #"
SELECT swName AS [Server], swRack AS [Rack], swEnvironment AS [Environment], swSunBeginTime AS [RebootTime], swSchedule as [Schedule]
FROM SW_SERVICE_LVL
INNER JOIN SW_SPECIALTY
ON swDiscount = swSpecialtyId
AND swEnvironment IN ( 'Cert', 'Test', 'Prod' )
AND swSchedule IN ( 'SCCM - Monthly' )
AND swGrpResp = 'MyGroup'
AND swRootObjectType = 'Server'
WHERE swSunday = 1
WHERE swName = $($props.Server)
"#
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $ServerQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$DataSet.Tables[0]
}
}#end process
End{
$SqlConnection.Close()
}
}#End function!
GetServer-RebootLookUp
Your query has two WHERE clauses. This isn't valid SQL.
Change this:
WHERE swSunday = 1
WHERE swName = $($props.Server)
To this:
WHERE swSunday = 1
AND swName = $($props.Server)
Also, you'll probably need to ensure it's properly quoted as a literal value. In general however, you should use a parameterized query for this sort of thing.

Powershell Function SQL Stored Procedure with Parameters

The error received is "The SqlParameterCollection only accepts non-null SqlParameter type objects, not SqlCommand objects." & "Procedure or function 'usp__SingleUpdateServerBackupPath' expects parameter '#decServerName', which
was not supplied."
PowerShell code:
Set-StrictMode -Version 1.0
function update-serverbackuppath {
param(
[Parameter(Mandatory=$True,ValueFromPipeLine=$True)][object[]]$inputobject
)
BEGIN {
$connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
$connection.ConnectionString = "server=servername;database=database;trusted_connection=yes"
$connection.Open()
}
PROCESS {
$UpdateBackupPath = New-Object -TypeName System.Data.SqlClient.SqlCommand
$UpdateBackupPath.Connection = $connection
$UpdateBackupPath.CommandText = "usp__SingleUpdateServerBackupPath"
$UpdateBackupPath.Commandtype = [System.Data.Commandtype]::StoredProcedure
$ParamUpdateBackupPath = New-Object -TypeName System.Data.SqlClient.SqlParameter
$ParamUpdateBackupPath.ParameterName = "#decBackupPath"
$ParamUpdateBackupPath.SqlDbType = [System.Data.SqlDbType]::VarChar
$ParamUpdateBackupPath.Direction = [System.Data.ParameterDirection]::Input
$ParamUpdateBackupPath.Value = $inputobject.paths
$ParamUpdateBackupPathServerName = New-Object -TypeName System.Data.SqlClient.SqlCommand
$ParamUpdateBackupPathServerName.ParameterName = "#decServerName"
$ParamUpdateBackupPathServerName.SqlDbType = [System.Data.SqlDbType]::VarChar
$ParamUpdateBackupPathServerName.Direction = [System.Data.ParameterDirection]::Input
$ParamUpdateBackupPathServerName.Value = $inputobject.names
$UpdateBackupPath.Parameters.Add($ParamUpdateBackupPath)
$UpdateBackupPath.Parameters.Add($ParamUpdateBackupPathServerName)
$reader = New-Object -TypeName System.Data.SqlClient.SqlDataReader = $UpdateBackupPath.ExecuteReader()
}
END {
$connection.Close()
}
}
SQL Procedure:
Create Procedure usp__SingleUpdateServerBackupPath
(
#decBackupPath AS varchar(50),
#decServerName AS varchar(50)
)
AS
UPDATE BCKP
SET PTH = #decBackupPath
FROM BCKP
INNER JOIN SRVR
ON SRVR.ID = BCKP.FK_SRVR
WHERE SRVR.NM = #decServerName
CSV File Format
Import-Csv -Path C:\Bin\Repos\Backup.csv | C:\Bin\Scripts\update-serverbackuppath.ps1
Names Paths
Server1 \\fileshare\server_name
The Powershell code has several syntax errors, like referring to enums in erroneus a way:
# Incorrect form
[System.Data.Commandtype.StoredProcedure]
# Correct form for referring to enumeration
[System.Data.Commandtype]::StoredProcedure
Later on, there is an undeclared object which's member method is called:
# $command is not set, so ExecuteReader method is available
$reader = $command.ExecuteReader()
It is highly recommended to use strict mode in Powershell. It helps catching typos by preventing access to non-existing properties an uninitialized variables.
Edit
After the updated code, there are still two errors:
# This doesn't make sense. The variable should be SqlParameter, not SqlCommand
$ParamUpdateBackupPathServerName = New-Object -TypeName System.Data.SqlClient.SqlCommand
# Like so:
$ParamUpdateBackupPathServerName = New-Object -TypeName System.Data.SqlClient.SqlParameter
# This is nonsense syntax
$reader = New-Object -TypeName System.Data.SqlClient.SqlDataReader = $UpdateBackupPath.ExecuteReader()
# Like so:
$reader = $UpdateBackupPath.ExecuteReader()

Powershell script to import log file into SQL table

I'm wanting to import a log file into sql table using powershell. Has anyone does this?
The log has some structure at the bottom but I would like to skip the top 13 rows.
Sample Log: https://lh6.googleusercontent.com/yFajtwkfT73JqojMiEZMz-_1cy6XQlHtqP5ibkJbfpM=w484-h228-p-no
Powershell script for SQL connection:
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=Server\Development;Database=Development;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "BULK INSERT Development..CUBE_LOG
FROM 'D:\POWERCUBE_SQL_LOG\result.txt'
WITH (CODEPAGE='RAW' ,FIELDTERMINATOR = '|',ROWTERMINATOR = '\n', DATAFILETYPE='widechar')"
$SqlCmd.Connection = $SqlConnection
$SqlConnection.Open()
$sqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
Use the First Row Argument in bulk insert.
Reference : http://technet.microsoft.com/en-us/library/ms188365.aspx
WITH (CODEPAGE='RAW' ,FIELDTERMINATOR = '|',ROWTERMINATOR = '\n',FIRSTROW = 14,DATAFILETYPE='widechar')"

Add SQL Server Instances to Central Management Server Groups with Powershell

I am trying to create a script to automatically iterate through a text file of all our SQL Server instances and add each on if it doesn't already exist to the CMS. I want to try doing this through SMO instead of hardcoding sql strings in. Below is what I have so far but it doesn't seem to be working. Any help would be appreciated. Thanks.
Eventually I will add more If statements in to distribute the instances to certain groups but for now I'm just trying to get it to populate everything.
$CMSInstance = "cmsinstancename"
$ServersPath = "C:\Scripts\InPutFiles\servers.txt"
#Load SMO assemplies
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Management.RegisteredServers') | out-null
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Management.Common') | out-null
$connectionString = "Data Source=$CMSINstance;Initial Catalog=master;Integrated Security=SSPI;"
$sqlConnection = new-object System.Data.SqlClient.SqlConnection($connectionString)
$conn = new-object Microsoft.SqlServer.Management.Common.ServerConnection($sqlConnection)
$CMSStore = new-object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore($conn)
$CMSDBStore = $CMSStore.ServerGroups["DatabaseEngineServerGroup"]
$Servers = Get-Content $ServersPath;
foreach($Server in $Servers)
{
#Put this in loop to deal with duplicates in list itself
$AlreadyRegisteredServers = #()
$CMSDBStore.GetDescendantRegisteredServers()
$RegServerName = $Server.Name
$RegServerInstance = $Server.Instance
if($AlreadyRegisteredServers -notcontains $RegServerName)
{
Write-Host "Adding Server $RegServerName"
$NewServer = New-Object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServer($CMSDBStore, "$RegServerName")
$NewServer.SecureConnectionString = "server=$RegServerInstance;integrated security=true"
$NewServer.ConnectionString = "server=$RegServerInstance;integrated security=true"
$NewServer.ServerName = "$RegServerInstance"
$NewServer.Create()
}
else
{
Write-Host "Server $RegServerName already exists - cannot add."
}
}
I cut your script down to just the basics and it works for me. I did have to change the connection command to work in my environment but other than that and registering a default instance of SQL Server there were no errors. Once I did a refresh of the CMS server the newly registered server was visible and accessible.
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Management.RegisteredServers') | Out-Null
$CMSInstance = 'CMS_ServerName'
$connectionString = "Data Source=$CMSInstance;Initial Catalog=master;Integrated Security=SSPI;"
$sqlConnection = new-object System.Data.SqlClient.SqlConnection($connectionString)
$conn = New-Object System.Data.SqlClient.SqlConnection("Server=$CMSInstance;Database=master;Integrated Security=True")
$CMSStore = new-object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore($conn)
$CMSDBStore = $CMSStore.ServerGroups["DatabaseEngineServerGroup"]
$RegServerName = 'ServerToRegister'
$RegServerInstance = $RegServerName
$NewServer = New-Object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServer($CMSDBStore, "$RegServerName")
$NewServer.SecureConnectionString = "server=$RegServerInstance;integrated security=true"
$NewServer.ConnectionString = "server=$RegServerInstance;integrated security=true"
$NewServer.ServerName = "$RegServerInstance"
$NewServer.Create()