Question

Read and write SQL table with powershell

Asked by: caseman22

I have a script that searches the file system for a string then if found copies the file to a destination directory. these parameters are in the ps1 file. I want to be able to put these parameters in a table and also log the results to a seperate table. How can i do this?

$sPath = "c:\"
$sSearchStr = "nbjoe"
$sCopyDest = "c:\stage"
 
Get-Childitem $sPAtH -recurse | Select-String $sSearchStr -List | % { Copy-Item -Path $_.Path -Destination $CopyDest }

                                  
1:
2:
3:
4:
5:

Select allOpen in new window

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-08-30 at 13:53:33ID24693522
Tags

powershell SQL

,

scripting

,

SQL

Topics

Powershell

,

Databases Miscellaneous

,

MS SQL Server

,

VB Script

,

VB Database Programming

Participating Experts
2
Points
500
Comments
43

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. SQL string Parameters
    How Can i call a Stored procedure AND pass in parameters in an SQL string. eg call Execute sp_SelectContacts and Passing 4,5,6,7
  2. PowerShell regex
    I have the following block of text: "The process started at 11:34:50 PM failed to create System.Discovery.Data, no errors detected in the output. The process exited with 0 Command executed: ""C:\WINDOWS\system32\cscript.exe"" /nologo ""D...
  3. MSACCESS 2003: "Destination" Table Name for Make…
    How do I make the Make-Table Query give me "parameter" options with a partial fill-in - for me to name the destination database for the export? Please see below. I want to have the option of naming those last few characters everytime (T6, T7, T8 - etc. ) SELECT ...
  4. PARSE EXCEL FILE INTO STRING SEPERATED BY COMMAS
    I receive Excel files daily. I would like to use Microsoft Access to read an Excel File, place the information into a string seperated by commas, or better yet, each cell placed in to an Array that I can use an SQL statement to inster into Access. My Excel file is named &qu...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: Chris-DentPosted on 2009-08-31 at 01:03:08ID: 25221136


Used System.Data.SQLClient before? That's what you'd be using to talk to an SQL database for both retrieving data and updating tables.

Chris

 

by: caseman22Posted on 2009-08-31 at 06:07:22ID: 25222428

Chris, I have used it in VBScript but I'm new to PS and was trying to figure out how to read and use in PS.

 

by: Chris-DentPosted on 2009-09-02 at 02:28:06ID: 25239181


There are some good examples out there:

http://sqlblog.com/blogs/allen_white/archive/2008/01/25/using-powershell-and-sql-server-together.aspx

I used the same to build mine. If you can tell me the queries you'd like to run I'm sure I could help put that in context.

Chris

 

by: caseman22Posted on 2009-09-02 at 13:26:45ID: 25245293

Well basically I want read one line at a time from the BD then search for file based on that info then copy the file then log the file, path and destination to a SQL table. Here is what I have so far. I know it very rough so please excuse my mess. lol. I am able to query the table and get back info but it doesnt read into the gci command and it doesnt write to sql.

There are 2 tables one for params and one for logging. All fields are setup for varchar.

Any help is appreciated. Thank you in advance.
Joe

$SQLDB = "ServerAutomation"
$sDate = Get-Date
 
function Get-SqlParms {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
$SQLConnection.ConnectionString = "Server=$SQLSERVER;Database=$SQLDB;Integrated Security=True" 
$SqlCommandText = "select * from FileMoveParms" 
$SQLConnection.Open()
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand($SqlCommandText, $SQLConnection)
	$reader = $SqlCmd.ExecuteReader()
	while ($reader.read())
	{ $sServer = $reader["server"].Tostring()
		$sPath = $reader["path"].tostring()
		$sSearchS = $reader["searchstring"].tostring()
		$scopydest = $reader["copydest"].tostring()
						
		$UNCPath = "`"\\$sServer\$sPath`""
						
		$sSearchs = "`"$sSearchs`""
		$sCopydest = "`"$sCopydest`""
				
	}
# for debugging
#Write-Host "$sServer", "$sPath", "$sSearchs", "$scopydest"
#Write-Host $UNCPath
}
 
 
function Log-ToSQL
{
	$SQLCn = New-Object System.Data.SqlClient.SqlConnection
	$SQLCn.ConnectionString = "Server=$SQLServer;Database=$SQDB;Integrated Security=True"
	$SQLCn.Open()
	$SQLCMD = $SQLCn.CreateCommand() 
	$SQLCMD.CommandText = " INSERT Into $SQLLogs (server, path, filename, copydate, copiedto) values ('$sServer', '$_.Path', '$_.item', '$sDate', '$sCopyDest')"
 
	$Results = $SQLCMD.ExecuteNonQuery()
	$SQLCN.Close()
}
 
Get-Sqlparms
 
gci $UNCPath -recurse | Select-String $sSearchs -List | % { Copy-Item -Path $_.Path -Destination $sCopyDest } | % {Log-ToSql}
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:

Select allOpen in new window

 

by: rrjegan17Posted on 2009-09-08 at 21:23:54ID: 25288212

Haven't used Powershell to this extent by reading and writing SQL Server Tables.
Anyhow read it long time back on this one.

Kindly check this one out..

http://msdn.microsoft.com/en-us/library/cc281954.aspx
http://msdn.microsoft.com/en-us/library/cc281962.aspx

 

by: Chris-DentPosted on 2009-09-09 at 01:18:40ID: 25289141


Sorry, forgot to reply.

Lets take a look...

First you have to deal with scoping. That is, the variables you create and use within the function Get-SqlParms don't exist outside of that.

I believe this is why you're running into problems writing back, a lot of null values in there.

We either need to make Get-SqlParms return information, or we need to remove the functions entirely. I've gone with the latter here, it's simpler for now.

And finally, I'm making assumptions about what you want from the logging, so yell if it's not correct.

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date).DateTime 
 
$SqlConnection = New-Object Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True" 
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
 
$Reader = $SqlCmd.ExecuteReader()
 
While ($Reader.Read())
{
  $sServer = $Reader["server"].Tostring()
  $sPath = $Reader["path"].tostring()
  $sSearchS = $Reader["searchstring"].tostring()
  $scopydest = $Reader["copydest"].tostring()
                                                
  $UNCPath = "\\$sServer\$sPath"
                                                
  $sSearchs = "$sSearchs"
  $sCopydest = "$sCopydest"
 
  Get-ChildItem $UNCPath -Recurse | Select-String -Pattern $sSearchS -List | %{
    Copy-Item -Path $_.Path -Destination $sCopyDest
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ('$sServer', '$_.Path', '$_.FileName', '$sDate', '$sCopyDest')"
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 05:27:50ID: 25290401

Chris, thanks for that.
Here is the error i get when i run what you created. It does copy the files but does not write log to sql.

Exception calling "ExecuteNonQuery" with "0" argument(s): "There is already an
open DataReader associated with this Command which must be closed first."
At C:\Documents and Settings\user\My Documents\
tions3.ps1:74 char:38
+         $Results = $SqlCmd2.ExecuteNonQuery( <<<< )



rrjegan17, thanks for the info, i will look into that as well.

 

by: Chris-DentPosted on 2009-09-09 at 05:37:37ID: 25290477


Ahh okay, in that case can we see if this works?

Still using the same SQL Connection, hopefully it's happy with $Reader.Close().

And it would be worth checking the contents of $SqlData to see if it read that into an object correctly.

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date).DateTime 
 
$SqlConnection = New-Object Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True" 
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
 
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @()
While ($Reader.Read())
{
  $SqlData += $Reader | Select-Object `
    @{n='Server';e={ $_["server"].ToString() }}, `
    @{n='Path';e={ $_["path"].ToString() }}, `
    @{n='SearchString';e={ $_["searchstring"].ToString() }}, `
    @{n='CopyDest';e={ $_["copydest"].ToString() }}
}
 
$Reader.Close()
 
ForEach ($Item in $SqlData) 
{
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | %{
    Copy-Item -Path $_.Path -Destination $Item.CopyDest
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ($Item.Server, '$_.Path', '$_.FileName', $Date, $Item.CopyDest)"
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 06:32:50ID: 25291006

Nope $SqlData is null.

 

by: Chris-DentPosted on 2009-09-09 at 06:40:51ID: 25291104


Okie dokie. Another try...

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date).DateTime 
 
$SqlConnection = New-Object Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True" 
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
 
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @()
While ($Reader.Read())
{
  $SqlData += "" | Select-Object `
    @{n='Server';e={ $Reader["server"].ToString() }}, `
    @{n='Path';e={ $Reader["path"].ToString() }}, `
    @{n='SearchString';e={ $Reader["searchstring"].ToString() }}, `
    @{n='CopyDest';e={ $Reader["copydest"].ToString() }}
}
 
$Reader.Close()
 
ForEach ($Item in $SqlData) 
{
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | %{
    Copy-Item -Path $_.Path -Destination $Item.CopyDest
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ($Item.Server, '$_.Path', '$_.FileName', $Date, $Item.CopyDest)"
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 06:45:19ID: 25291159

Getting there :)  (you're awesome)

Now we get this error

Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near '('."
At \path to script\ServerMigration4.ps1:64 char:37
+         $Results = $SqlCmd.ExecuteNonQuery( <<<< )

refering to
 $Results = $SqlCmd.ExecuteNonQuery()

But now $SqlData contains information when checked before the for each statment.

 

by: Chris-DentPosted on 2009-09-09 at 06:47:43ID: 25291183


Ah sorry, I broke the query. Try this?

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date).DateTime 
 
$SqlConnection = New-Object Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True" 
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
 
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @()
While ($Reader.Read())
{
  $SqlData += "" | Select-Object `
    @{n='Server';e={ $Reader["server"].ToString() }}, `
    @{n='Path';e={ $Reader["path"].ToString() }}, `
    @{n='SearchString';e={ $Reader["searchstring"].ToString() }}, `
    @{n='CopyDest';e={ $Reader["copydest"].ToString() }}
}
 
$Reader.Close()
 
ForEach ($Item in $SqlData) 
{
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | %{
    Copy-Item -Path $_.Path -Destination $Item.CopyDest
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ('$($Item.Server)', '$_.Path', '$($_.FileName)', '$Date', '$($Item.CopyDest)')"
 
    # To confirm the query...
    Write-Host $SqlCmd.CommandText
 
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 06:58:41ID: 25291336

still get this
Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax nea
r '('."
At c:\pathtoscript\ServerMigration4.ps1:67 char:37

but the query echos back with only partial info like this
INSERT INTO  (server, path, filename, copydate, copiedto) VALUES ('server', '\\server\c$\compaq\hpdiags\hpdiags.exe:1402:@

 

by: Chris-DentPosted on 2009-09-09 at 07:55:48ID: 25291933


Okay, lets take a look at each of the values returned. Since the first bit is working I've skipped that, may as well work with the $SqlData object for now.

I think one of these must be more than a simple string.

Chris

ForEach ($Item in $SqlData) 
{
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | %{
    Copy-Item -Path $_.Path -Destination $Item.CopyDest
 
    Write-Host "Server:      $($Item.Server)"
    Write-Host "Path:        $($_.Path)"
    Write-Host "FileName:    $($_.FileName)"
    Write-Host "Date:        $Date"
    Write-Host "Destination: $($Item.CopyDest)"
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ('$($Item.Server)', '$_.Path', '$($_.FileName)', '$Date', '$($Item.CopyDest)')"
 
    # To confirm the query...
    # Write-Host $SqlCmd.CommandText
 
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 12:05:03ID: 25294460

The data that we get are the expected results. I'm not sure why ExecuteNonQuery is expecting arguments. I have tried to twist a couple different ways and I still can't get it to write to the table. If i do a simple insert like below it works fine.(SQL insert that is)

$conn = New-Object system.data.sqlclient.sqlconnection("data source=someserver; initial catalog=ServerAutomation; integrated security=sspi")
$conn.open()
$date = (Get-Date -format g)
$cmd = $conn.createcommand()
$cmd.commandtext = "INSERT FileMoveLogs VALUES ('server', 'path', 'filename', '$date', 'copiedto')"
$cmd.executenonquery()
$conn.close()
                                              
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window

 

by: Chris-DentPosted on 2009-09-09 at 12:10:47ID: 25294509


Does it still show the odd formatting if we echo out the CommandText as we did before?

Chris

 

by: caseman22Posted on 2009-09-09 at 12:21:07ID: 25294609

Well this is what i get.

INSERT INTO  (server, path, filename, copydate, copiedto) VALUES ('servername', '\\servername\c$\compaq\network\test2.txt:1:insight.Path', 'test2.txt', '9/9/2009 3:14 PM', '\\servername\c$\joetest\dest')

The second item should only be '\\servername\c$\compaq\network\test2.txt' Where is the :1:insight.Path coming from? and not sure how to get rid of it. Other than that it looks ok.

 

by: Chris-DentPosted on 2009-09-09 at 12:31:45ID: 25294721


Hmm looks like I missed the sub-expression off that one.

Once more?

Chris

ForEach ($Item in $SqlData) 
{
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | %{
    Copy-Item -Path $_.Path -Destination $Item.CopyDest
 
    $SqlCmd.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', '$Date', '$($Item.CopyDest)')"
 
    # To confirm the query...
    Write-Host $SqlCmd.CommandText
 
    $Results = $SqlCmd.ExecuteNonQuery()
  }
}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-09 at 12:39:25ID: 25294785

statement looks correct now: what did you change?

INSERT INTO  (server, path, filename, copydate, copiedto) VALUES ('server', '\\server\c$\compaq\network\test2.txt', 'test2.txt', '9/9/2009 3:37 PM', '\\server\c$\joetest\dest')

But I still get that error
Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near '('."

 

by: caseman22Posted on 2009-09-09 at 12:40:12ID: 25294793

oh wait table name is missing

 

by: Chris-DentPosted on 2009-09-09 at 12:43:36ID: 25294817


Still errors if the table name is fixed?

Chris

 

by: caseman22Posted on 2009-09-09 at 12:43:56ID: 25294820

Now it works since the addition of the table variable. lol dumb stuff. Let me finish testing it.

You are the man!

 

by: caseman22Posted on 2009-09-09 at 13:11:30ID: 25295107

Here is the final product. I created two connection and enabled MARS. The only gotcha is that it will copy the file even if it exists on the destination and write to the table that it was moves. It would be nice if it would not copy the file and insert a record if the file was already there, but it's not a big deal. let me know wheat you think.
Joe

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
$SqlLogs = "FileMoveLogs"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date -format g)
 
$SqlConnection = New-Object system.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True"
$SqlConnection2 = New-Object system.Data.SqlClient.SqlConnection ("Data Source=$SqlServer; Initial Catalog=$SqlDB; Integrated Security=SSPI")
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlConnection2.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
$sqlcmd2 = $SqlConnection2.createcommand()
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @( )
while ($Reader.Read())
{
	$SqlData += "" | Select-Object `
	@{ n = 'Server' ; e = { $Reader["server"].ToString() } }, `
	@{ n = 'Path' ; e = { $Reader["path"].ToString() } }, `
	@{ n = 'SearchString' ; e = { $Reader["searchstring"].ToString() } }, `
	@{ n = 'CopyDest' ; e = { $Reader["copydest"].ToString() } }
}
 
$Reader.Close()
foreach ($Item in $SqlData)
{ 
Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | Select-String -Pattern $Item.SearchString -List | % {
	Copy-Item -Path $_.Path -Destination $Item.CopyDest
			 
	$SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', '$Date', '$($Item.CopyDest)')"
			 
	# To confirm the query...
			 
	$Results = $SqlCmd2.ExecuteNonQuery()
	}
}
$SqlConnection.close()
$SqlConnection2.close()
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:

Select allOpen in new window

 

by: Chris-DentPosted on 2009-09-09 at 13:43:21ID: 25295361


Lets chuck in a test for the file path then :)

Does "CopyTo" include the file name? I'm assuming not in the code below.

Chris

 

by: Chris-DentPosted on 2009-09-09 at 13:48:19ID: 25295406


Okay... helps if I actually include the code :)

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
$SqlLogs = "FileMoveLogs"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date -format g)
 
$SqlConnection = New-Object system.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True"
$SqlConnection2 = New-Object system.Data.SqlClient.SqlConnection ("Data Source=$SqlServer; Initial Catalog=$SqlDB; Integrated Security=SSPI")
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlConnection2.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
$sqlcmd2 = $SqlConnection2.createcommand()
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @( )
while ($Reader.Read())
{
  $SqlData += "" | Select-Object `
    @{ n = 'Server' ; e = { $Reader["server"].ToString() } }, `
    @{ n = 'Path' ; e = { $Reader["path"].ToString() } }, `
    @{ n = 'SearchString' ; e = { $Reader["searchstring"].ToString() } }, `
    @{ n = 'CopyDest' ; e = { $Reader["copydest"].ToString() } }
}
 
$Reader.Close()
foreach ($Item in $SqlData)
{ 
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | `
    Select-String -Pattern $Item.SearchString -List | % {
 
    If (Test-Path "$($Item.CopyDest)\$($_.FileName)")
    {
      # File Exists
      # Execute SQL Command here
    }
    Else
    {
      Copy-Item -Path $_.Path -Destination $Item.CopyDest
			 
      $SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
        "copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', " + `
        "'$Date', '$($Item.CopyDest)')"
	
      $Results = $SqlCmd2.ExecuteNonQuery()
    }
  }
}
$SqlConnection.close()
$SqlConnection2.close()

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-10 at 06:46:46ID: 25300121

Chris,
Yes that does work, however i may go a different route, a little. I may want duplicate name but would need to increment them by say 1. so the file name that is copied would be text.txt1 and would be the same in the database for logging. That way if it come across multiple configuration files with the same name we will have them all. Take IIS for instance. You may have multiple sites with the same file structure and same config file names. well i want them all.

So....
i want to say if the file already exists in destination then add a unique number to the end of the filename and copy the file and log with the same name.

sound good? any thought or ideas?

Joe

Thanks again for all your help!

 

by: Chris-DentPosted on 2009-09-10 at 07:10:57ID: 25300379


Hmm I think this should do that...

Chris

$SqlServer = "SomeServer"
$SqlDB = "ServerAutomation"
$SqlLogs = "FileMoveLogs"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date -format g)
 
$SqlConnection = New-Object system.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True"
$SqlConnection2 = New-Object system.Data.SqlClient.SqlConnection ("Data Source=$SqlServer; Initial Catalog=$SqlDB; Integrated Security=SSPI")
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlConnection2.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
$sqlcmd2 = $SqlConnection2.createcommand()
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @( )
while ($Reader.Read())
{
  $SqlData += "" | Select-Object `
    @{ n = 'Server' ; e = { $Reader["server"].ToString() } }, `
    @{ n = 'Path' ; e = { $Reader["path"].ToString() } }, `
    @{ n = 'SearchString' ; e = { $Reader["searchstring"].ToString() } }, `
    @{ n = 'CopyDest' ; e = { $Reader["copydest"].ToString() } }
}
 
$Reader.Close()
foreach ($Item in $SqlData)
{ 
  Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | `
    Select-String -Pattern $Item.SearchString -List | % {
 
    If (Test-Path "$($Item.CopyDest)\$($_.FileName)")
    {
      $i = 1; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
      Do
      {
        $i++; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
      } Until ((Test-Path $Destination) -eq $False)
      Copy-Item -Path $_.Path -Destination $Destination
    }
    Else
    {
      Copy-Item -Path $_.Path -Destination $Item.CopyDest
			 
      $SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
        "copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', " + `
        "'$Date', '$($Item.CopyDest)')"
	
      $Results = $SqlCmd2.ExecuteNonQuery()
    }
  }
}
$SqlConnection.close()
$SqlConnection2.close()
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-10 at 08:50:50ID: 25301410

That works well.

One problem now. Whenever i run any version of the above script it writes the first two files to the table then gets "InputStream" and stops writing to the table.

I inserted a "Write-Host $_.filename" before the SQL Query to see what files were found.

I have seen some similar post that had the same issue and the fixed by using Get-Item instead of Get-Contents but that doesnt work for searching all subfolders.
Joe

 

by: Chris-DentPosted on 2009-09-10 at 08:56:11ID: 25301483


Hmmm what do you mean by gets InputStream?

Chris

 

by: caseman22Posted on 2009-09-10 at 08:59:55ID: 25301514

when i add "Write-Host $_.filename" or "Write-Host $_.path" to the script it echos back "InputStream" and in the sql table the path and filename fields have "InputStream" listed and then the script no longer write to sql even if the script echos back more files.

 

by: Chris-DentPosted on 2009-09-10 at 09:01:05ID: 25301527


Hmm odd... I guess you don't see entries for that in the $SqlData object?

Chris

 

by: caseman22Posted on 2009-09-10 at 09:03:19ID: 25301551

no, that is only reading a couple records vs reading and entire c drive

 

by: caseman22Posted on 2009-09-10 at 09:18:48ID: 25301720

so far when i search through c:\windows it seems ok. still letting it run. not sure what the issues could be.

 

by: caseman22Posted on 2009-09-10 at 11:51:42ID: 25303119

Found this when i get help on select-string. Not quite sure what this means look at >>>>>>
If not from a file what would it be and why would it stop writing to SQL?

RETURN TYPE
    If the Quiet parameter is specified, a boolean value indicating whether the pattern was found.

    Otherwise, the output will be a set of MatchInfo objects, each of which have the following properties:
    IgnoreCase: Boolean
    LineNumber: integer (0 if input is not from a file)
    Line: string
   >>>> Filename: string ("InputStream" if input is not from a file)
    >>>>Path: string ("InputStream" if input is not from a file)
    Pattern: the string that was actually matched
    OriginalObject: object that was processed

 

by: caseman22Posted on 2009-09-11 at 07:30:45ID: 25309868

Chris,
I changed the field in the table to be data type text instead of varchar(50). The path string was too long and wasn't populating the field and now I'm not seeing the InputString message. Weird stuff.
I think we can close this guy out. I will finalize it with some tweaks and re-post the final code so anyone can enjoy. Thanks again for all your help. I really appreciate it.

Joe

 

by: Chris-DentPosted on 2009-09-11 at 07:32:44ID: 25309884


Hmm sorry I forgot to post again. That is really odd though.... Anyway, as long as it's working for you :)

Chris

 

by: caseman22Posted on 2009-09-11 at 10:19:40ID: 25311575

Here is the final code.


$SqlServer = "someserver"
$SqlDB = "ServerAutomation"
$SqlLogs = "FileMoveLogs"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date -format g)
 
$SqlConnection = New-Object system.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True"
$SqlConnection2 = New-Object system.Data.SqlClient.SqlConnection("Data Source=$SqlServer; Initial Catalog=$SqlDB; Integrated Security=SSPI")
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlConnection2.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
$sqlcmd2 = $SqlConnection2.createcommand()
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @( )
while ($Reader.Read())
{
	$SqlData += "" | Select-Object `
	@{ n = 'Server' ; e = { $Reader["server"].ToString() } }, `
	@{ n = 'Path' ; e = { $Reader["path"].ToString() } }, `
	@{ n = 'SearchString' ; e = { $Reader["searchstring"].ToString() } }, `
	@{ n = 'CopyDest' ; e = { $Reader["copydest"].ToString() } }
}
 
$Reader.Close()
foreach ($Item in $SqlData)
{
	Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | `
	Select-String -Pattern $Item.SearchString -List -exclude *.lnk* | % {
		 
		if (Test-Path "$($Item.CopyDest)\$($_.FileName)")
		{
			$i = 1 ; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
			do
			{
				$i++ ; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
			} until ( (Test-Path $Destination) -eq $False )
			Copy-Item -Path $_.Path -Destination $Destination
			$Date = (Get-Date -format g)
Write-Host $_.path
$SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
"copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)$i', " + `
"'$Date', '$($Item.CopyDest)')"
				
$Results = $SqlCmd2.ExecuteNonQuery()
		}
		else
		{
			Copy-Item -Path $_.Path -Destination $Item.CopyDest
			$Date = (Get-Date -format g)
			Write-Host $_.filename
			$SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
			"copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', " + `
			"'$Date', '$($Item.CopyDest)')"
				
			$Results = $SqlCmd2.ExecuteNonQuery()
		}
	}
}
$SqlConnection.close()
$SqlConnection2.close()

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-11 at 10:21:04ID: 31622296

Great work Chris! Thanks again. Hopefully i can return the help some day.

 

by: caseman22Posted on 2009-09-15 at 12:23:05ID: 25338296

Chris, the InputStream is caused by invalid data, in this case a "Directory" name. Directories do no have a property of .filename or .path. I can write and If statement to exclude the directory type but when you use select-string it does not pass the .fullname and .name property that I would need to put in the database. How can I take the directory name and put the .fullname in one column and "directory" in the filename column. any ideas?

 

by: Chris-DentPosted on 2009-09-16 at 03:16:11ID: 25343785


We can exclude directories here:

Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | `

With:

Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | ?{ $_PsIsContainer -eq $False } | `

Does that work to drop directories for you? Or is that what you'd already done?

Chris

$SqlServer = "someserver"
$SqlDB = "ServerAutomation"
$SqlLogs = "FileMoveLogs"
# This returns an Object not a string. Pulling the DateTime string from the object.
$Date = (Get-Date -format g)
 
$SqlConnection = New-Object system.Data.SqlClient.SqlConnection 
$SqlConnection.ConnectionString = "Server=$SqlServer;Database=$SqlDB;Integrated Security=True"
$SqlConnection2 = New-Object system.Data.SqlClient.SqlConnection("Data Source=$SqlServer; Initial Catalog=$SqlDB; Integrated Security=SSPI")
 
$SqlCommandText = "SELECT * FROM FileMoveParms" 
$SqlConnection.Open()
$SqlConnection2.Open()
$SqlCmd = New-Object Data.SqlClient.SqlCommand($SqlCommandText, $SqlConnection)
$sqlcmd2 = $SqlConnection2.createcommand()
$Reader = $SqlCmd.ExecuteReader()
 
$SqlData = @( )
while ($Reader.Read())
{
	$SqlData += "" | Select-Object `
	@{ n = 'Server' ; e = { $Reader["server"].ToString() } }, `
	@{ n = 'Path' ; e = { $Reader["path"].ToString() } }, `
	@{ n = 'SearchString' ; e = { $Reader["searchstring"].ToString() } }, `
	@{ n = 'CopyDest' ; e = { $Reader["copydest"].ToString() } }
}
 
$Reader.Close()
foreach ($Item in $SqlData)
{
	Get-ChildItem "\\$($Item.Server)\$($Item.Path)" -Recurse | `
        ?{ $_.PsIsContainer -eq $False } | `
	Select-String -Pattern $Item.SearchString -List -exclude *.lnk* | % {
		 
		if (Test-Path "$($Item.CopyDest)\$($_.FileName)")
		{
			$i = 1 ; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
			do
			{
				$i++ ; $Destination = "$($Item.CopyDest)\$($_.FileName)$i"
			} until ( (Test-Path $Destination) -eq $False )
			Copy-Item -Path $_.Path -Destination $Destination
			$Date = (Get-Date -format g)
Write-Host $_.path
$SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
"copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)$i', " + `
"'$Date', '$($Item.CopyDest)')"
				
$Results = $SqlCmd2.ExecuteNonQuery()
		}
		else
		{
			Copy-Item -Path $_.Path -Destination $Item.CopyDest
			$Date = (Get-Date -format g)
			Write-Host $_.filename
			$SqlCmd2.CommandText = "INSERT INTO $SQLLogs (server, path, filename, copydate, " + `
			"copiedto) VALUES ('$($Item.Server)', '$($_.Path)', '$($_.FileName)', " + `
			"'$Date', '$($Item.CopyDest)')"
				
			$Results = $SqlCmd2.ExecuteNonQuery()
		}
	}
}
$SqlConnection.close()
$SqlConnection2.close()
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:

Select allOpen in new window

 

by: caseman22Posted on 2009-09-16 at 11:51:09ID: 25348785

Chris, that works too. Thanks again for your help.

Joe

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...