Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Phone
Jul 30, 2005

親子丼をほしい。

Jelmylicious posted:

e: Aparently Get-Eventlog System should work too, so your second line should work as intended. Apart from it not showing the full info in your text file. So, at least use the export-csv.

And then cry when the formatting is all messed up.

Adbot
ADBOT LOVES YOU

bluegoon
Mar 5, 2010

by Pragmatica
Thanks man, appreciate the help.

bluegoon
Mar 5, 2010

by Pragmatica

Phone posted:

And then cry when the formatting is all messed up.

Piped with Format-List at the end? Would that help?

Phone
Jul 30, 2005

親子丼をほしい。
Export-CSV is awesome and works most of the time, but when you get on one of those edge cases where whatever list of data you're trying to enumerate and get into a readable format it sucks.

Luckily Technet has a ton of stuff about PS and a decent # of articles about piping stuff to Export-CSV.

Jelmylicious
Dec 6, 2007
Buy Dr. Quack's miracle juice! Now with patented H-twenty!
My quick test showed a nice CSV cooming from this, so I figured it would fit here. I always try using it first, if it doesn't work, then I start looking at alternatives/fixing it.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

kampy posted:

I would just modify the script a bit, or perhaps just run something like:
code:
$dupes = .\unmodifiedscriptfromtheweb.ps1 c:\whatever\path
foreach ($dupe in $dupes)
{
	foreach ($d in $dupe.Group)
	{
		# Change $d.Name to $d.FullName for the full path.
		"{0} *{1}" -f $dupe.Name, $d.Name
	}
	write-host ""
}
You could also modify the script a bit so that it produces a prettier md5 output by modifying the Get-MD5 function to something like this:
code:
function Get-MD5([System.IO.FileInfo] $file = $(throw ‘Usage: Get-MD5 [System.IO.FileInfo]‘))
{
# This Get-MD5 function sourced from:
# [url]http://blogs.msdn.com/powershell/archive/2006/04/25/583225.aspx[/url]
$stream = $null;
$cryptoServiceProvider = [System.Security.Cryptography.MD5CryptoServiceProvider];
$hashAlgorithm = new-object $cryptoServiceProvider
$stream = $file.OpenRead();
$hashByteArray = $hashAlgorithm.ComputeHash($stream);
$stream.Close();

## We have to be sure that we close the file stream if any exceptions are thrown.
trap
{
if ($stream -ne $null) { $stream.Close(); }
break;
}

foreach ($byte in $hashByteArray)
{
	$returnme += $byte.ToString("x2")
}
return $returnme
}
Edit:
You could also do something like this:
code:
$output = ""
$dupes = .\unmodifiedscriptfromtheweb.ps1 c:\whatever\path
foreach ($dupe in $dupes)
{
	foreach ($d in $dupe.Group)
	{
		$whatwewant = @{md5=$dupe.Name; filename=$d.Name}
		[array] $output += new-object psobject -property $whatwewant
	}
}
$output

Sorry for the late reply, but thanks for the help. The project got backburnered for a while and we ended up just deleting all the files and redownloading and enforcing unique names on creation. But I'm going to keep this around regardless, thanks!

adaz
Mar 7, 2009

Phone posted:

Export-CSV is awesome and works most of the time, but when you get on one of those edge cases where whatever list of data you're trying to enumerate and get into a readable format it sucks.

Luckily Technet has a ton of stuff about PS and a decent # of articles about piping stuff to Export-CSV.

Honestly I never trust Export-CSV anymore and just use my own custom objects added to a list then export that. I've run into more cases where it doesn't work than where it does.

code:
$exportTable = @()

$CustomOBJ = "" | select name,phone,blah
$customObj.Name = "blah"
$customObj.phone = "555-555-5555"
$customObj.blah = "hi, export-csv sucks"

$exportTable += $customObj

$exportTable | export-CSv C:\temp\blah.csv -noTypeInformation

adaz fucked around with this message at 02:36 on Nov 24, 2011

Moey
Oct 22, 2010

I LIKE TO MOVE IT

adaz posted:

Honestly I never trust Export-CSV anymore and just use my own custom objects added to a list then export that. I've run into more cases where it doesn't work than where it does.

This is awesome. I will probably work towards doing this for some of the things I am setting up. I finally have some free time so I started getting into my PS book. We have alot of user accounts in AD that are missing phone numbers, so I wrote/modified a little script to give me the names of these accounts. I figure next step is let it take arguments (or build it a little gui) so I can search for other empty attributes and allow it to select which OU to search instead of just the root of our users OU.

adaz
Mar 7, 2009

Moey posted:

This is awesome. I will probably work towards doing this for some of the things I am setting up. I finally have some free time so I started getting into my PS book. We have alot of user accounts in AD that are missing phone numbers, so I wrote/modified a little script to give me the names of these accounts. I figure next step is let it take arguments (or build it a little gui) so I can search for other empty attributes and allow it to select which OU to search instead of just the root of our users OU.

Yep, this is a good idea and one of the many tasks Powershell is perfectly suited for. Even better if you can feed it data from SQL/CSV or whatever and let it fill in the phone number for you.

ALso there was a typo in that code snippet, I fixed it just now.

Rabid Snake
Aug 6, 2004



Is there anyway to automate this process with Windows Office 2010? I want to copy a table from a Microsoft Word document and paste it in excel.

I wrote code that opens up a folder of .docx files, copies the whole table, opens up a specific Excel file, and than I'm stuck at appending (pasting) the table to the excel file. I'd assume that Powershell has access to the clipboard provided in Office 2010, correct?

adaz
Mar 7, 2009

Rabid Snake posted:

Is there anyway to automate this process with Windows Office 2010? I want to copy a table from a Microsoft Word document and paste it in excel.

I wrote code that opens up a folder of .docx files, copies the whole table, opens up a specific Excel file, and than I'm stuck at appending (pasting) the table to the excel file. I'd assume that Powershell has access to the clipboard provided in Office 2010, correct?

Yes it isn't too bad - how far does this Scripting Guys article on copying from excel/excel get you? Should cover what you need

http://blogs.technet.com/b/heyscriptingguy/archive/2010/09/08/copy-data-from-one-excel-spreadsheet-to-another-with-powershell.aspx

You'll be dealing with the Office Interop namespace primarily. let me know if you get stuck and I can look into explicitly how to do it (I don't know off the top of my head, sorry :))

Hypnobeard
Sep 15, 2004

Obey the Beard



Howdy.

I'm running into a frustrating issue trying to send a simple SMTP message from a server in Powershell v1.

Here's the relevant portion of the script; the attachment is present and the path is correct. (I've omitted some object dumps I've added in the course of troubleshooting for clarity.)

code:
$msg = new-object System.Net.Mail.MailMessage
$att = new-object System.Net.Mail.Attachment($file, 'text/plain')

$msg.subject = "subject"
$msg.body = "body"
$msg.Attachments.Add($att)
$msg.To.Add("address1@host.com")
$msg.To.Add("address2@host.com")
$msg.From = "sender@host.com"

$smtpServer = "smtpserver address"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($msg)
This is creating the message fine, setting the sender, adding the attachment.. but it's refusing to add the recipients:

code:
From                        : [email]sender@host.com[/email]
Sender                      :
ReplyTo                     :
To                          : {, }
Bcc                         : {}
CC                          : {}
Priority                    : Normal
DeliveryNotificationOptions : None
Subject                     : subject
SubjectEncoding             :
Headers                     : {}
Body                        : body
BodyEncoding                : System.Text.ASCIIEncoding
IsBodyHtml                  : False
Attachments                 : {filename_of_attachement.csv}
AlternateViews              : {}
It doesn't matter if I create the MailAddress objects first and pass those to To.Add or specify a sender in the MailMessage constructor.

What am I doing wrong?

adaz
Mar 7, 2009

You're not doing anything wrong by that code sample I stared at it for like 10 minutes and can't see anything wrong. I mean just copy pasting that code block gets me this:




e: Oh you're using powershell v1. I don't have v1 handy anywhere to test it on, sec guessing it's because you're using an older version of the framework let me look at it.

e2: If you do $msg.To after constructing/adding the address what is outputted? Are DisplayName, User,Host,Address also all blank? Even by v2 of the framework you aren't doing anything wrong.

adaz fucked around with this message at 19:32 on Dec 2, 2011

Hypnobeard
Sep 15, 2004

Obey the Beard



adaz posted:

You're not doing anything wrong by that code sample I stared at it for like 10 minutes and can't see anything wrong. I mean just copy pasting that code block gets me this:




e: Oh you're using powershell v1. I don't have v1 handy anywhere to test it on, sec guessing it's because you're using an older version of the framework let me look at it.

e2: If you do $msg.To after constructing/adding the address what is outputted? Are DisplayName, User,Host,Address also all blank? Even by v2 of the framework you aren't doing anything wrong.

DisplayName is blank, User, Host and Address have the appropriate entries.

If it helps narrow it down, this is 64-bit Server 2008 Enterprise SP2 with the Windows Powershell feature installed.

I'm guessing we need either to install v2 or put in a later version of .NET (v2, 3, and 3.5 are currently installed).

Hypnobeard fucked around with this message at 20:44 on Dec 2, 2011

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!
How sure are you that you're running v1? I'm pretty sure 2008 SP2 has v2 already. Try looking at $psversiontable. If it exists, you're running v2. If not you are indeed on v1.

E: \/\/ I guess I was wrong, since that is definitely what one would expect from v1.

Jethro fucked around with this message at 21:36 on Dec 2, 2011

Hypnobeard
Sep 15, 2004

Obey the Beard



Jethro posted:

How sure are you that you're running v1? I'm pretty sure 2008 SP2 has v2 already. Try looking at $psversiontable. If it exists, you're running v2. If not you are indeed on v1.

$psversiontable doesn't exist (empty response). $Host.Version returns:

code:
PS Variable:\> $Host.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
1      0      0      0
So I'm pretty sure I'm on v1.

adaz
Mar 7, 2009

Tolan posted:

DisplayName is blank, User, Host and Address have the appropriate entries.

If it helps narrow it down, this is 64-bit Server 2008 Enterprise SP2 with the Windows Powershell feature installed.

I'm guessing we need either to install v2 or put in a later version of .NET (v2, 3, and 3.5 are currently installed).

Oh that's fine, displayname isn't a required attribute you don't need it to send email. For whatever reason with v1 it's not displaying address when you just check the $msg and output it to the shell but it should still send the actual email just fine. V2 looks like displays address by default or displayname if it's filled in. You can create a valid MailAddress with a displayname if you really care about how it shows up (http://msdn.microsoft.com/en-us/library/system.net.mail.mailaddress.aspx)

adaz fucked around with this message at 21:39 on Dec 2, 2011

Hypnobeard
Sep 15, 2004

Obey the Beard



adaz posted:

Oh that's fine, displayname isn't a required attribute you don't need it to send email. For whatever reason with v1 it's not displaying address when you just check the $msg and output it to the shell but it should still send the actual email just fine. V2 looks like displays address by default or displayname if it's filled in. You can create a valid MailAddress with a displayname if you really care about how it shows up (http://msdn.microsoft.com/en-us/library/system.net.mail.mailaddress.aspx)

I'm not too worried about the displayname; it's refusing to send the email period because of the lack of recipient. I guess the answer is upgrade to v2, which means it's time to start the approval process. Meh.

Thank you very much for the help. :)

adaz
Mar 7, 2009

Tolan posted:

I'm not too worried about the displayname; it's refusing to send the email period because of the lack of recipient. I guess the answer is upgrade to v2, which means it's time to start the approval process. Meh.

Thank you very much for the help. :)

Weird, it shouldn't care at all about display name. I was looking at some of my old code I know was created in the V1 days and I've never had to add a display name. So something like this won't work? It still whines about invalid recipient? There has to be something else going on here, in particular i'm wondering about that from part, it really shouldn't be displaying it like that from everything I remember, almost like it's html

code:
$to = [system.net.mail.mailaddress]"address1@host.com"
$from = [system.net.mail.mailaddress]"address2@host.com"

$msg = new-Object System.Net.Mail.MailMessage
$msg.to.add($to)
$msg.from = $from
$msg.subject = "blah"
$msg.body = "blah"

adaz fucked around with this message at 22:12 on Dec 2, 2011

Hypnobeard
Sep 15, 2004

Obey the Beard



adaz posted:

Weird, it shouldn't care at all about display name. I was looking at some of my old code I know was created in the V1 days and I've never had to add a display name. So something like this won't work? It still whines about invalid recipient? There has to be something else going on here, in particular i'm wondering about that from part, it really shouldn't be displaying it like that from everything I remember, almost like it's html

code:
$to = [system.net.mail.mailaddress]"address1@host.com"
$from = [system.net.mail.mailaddress]"address2@host.com"

$msg = new-Object System.Net.Mail.MailMessage
$msg.to.add($to)
$msg.from = $from
$msg.subject = "blah"
$msg.body = "blah"

Grrr. Turns out the McAfee client on the server was set to block port 25 transactions. Fixing that resolved the problem. It's still weird that it doesn't show the recipient addresses on the MailMessage object, though.

Again, thanks for the help.

adaz
Mar 7, 2009

Ahh that makes more sense. It's odd it didn't throw a connection refused error message though.

As far as displaying null on the addresses, just one of those things. The default display value must have been display name to the shell. They've definitely changed it in V2. Also you should put through that request to have v2 on your servers anyway, definitely not a bad idea.

Cronus
Mar 9, 2003

Hello beautiful.
This...is gonna get gross.
Version 2 also has the very easy to work with Send-MailMessage built in, and if you have .NET 4.0 you gain a lot of additional capabilities on top of that.

Drumstick
Jun 20, 2006
Lord of cacti
I am trying to identify and move disabled accounts within in AD. I am able to ID the account that are disabled but I am having problems getting the user account to move. The error that is appearing is in the $from.PSBase.Moveto. What am I missing?

Here is what I currently have
code:
$filter = "(&(objectClass=user)(objectCategory=person))"
$user = [adsi] "LDAP:// OU=xxx,DC=xxx,DC=xxx"

Foreach ($suser in $user.psbase.Children)
{
$user = [adsi]"LDAP://$($user.properties.item(""distinguishedname""))"
$uac=$user.psbase.invokeget ("useraccountcontrol")

if($uac -band 0x2){
 $from = [adsi] "LDAP://<currentlocation>"
 $NewOU = [adsi] "LDAP:// <Newlocation>"
$from.PSBase.MoveTo($NewOU)
}
}

adaz
Mar 7, 2009

Your MoveTo syntax is a bit off, for reference: http://msdn.microsoft.com/en-us/library/w8stwdkc.aspx


Code wise it looks like so:

code:
$user.PSBase.MoveTo($NewOU,"cn=$($user.name)")

Drumstick
Jun 20, 2006
Lord of cacti

adaz posted:

Your MoveTo syntax is a bit off, for reference: http://msdn.microsoft.com/en-us/library/w8stwdkc.aspx


Code wise it looks like so:

code:
$user.PSBase.MoveTo($NewOU,"cn=$($user.name)")

Bah, So close yet so far. That you so much. Made that change this morning and it ran exactly how I expected.

Rabid Snake
Aug 6, 2004



I've written a Powershell script that copies a table from Microsoft Word and pastes them to an excel document. I want to append it after the last used row in column A.

I got this code so far:
---
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$ExcelWordBook = $Excel.Workbooks.Open($ExcelPath)
$ExcelWorkSheet = $Excel.WorkSheets.item("Sheet1")
$ExcelWorkSheet.activate()

This is where I get confused, I want to be able to find the last row that is used in the Excel WorkSheet.

$lastRow = $ExcelWorkSheet.UsedRange.rows("A").count
$nextRow = $lastRow + 1
$ExcelWorkSheet.Range("A$nextRow").Select
$ExcelWorkSheet.Paste()

---
I feel like I'm so close after this. I was trying to use the UsedRange property in the Office Interlop to determine the last row in the Excel WorkSheet. (http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.usedrange(v=vs.80).aspx) Any ideas? I feel like I'm using the UsedRange function incorrectly.

adaz
Mar 7, 2009

You were really close. There are also some other ways of doing it including using specialCells property on the range interface.

code:
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$ExcelWordBook = $Excel.Workbooks.Open($ExcelPath)
$ExcelWorkSheet = $Excel.WorkSheets.item("sheet1")
$ExcelWorkSheet.activate()


$lastRow = $ExcelWorkSheet.UsedRange.rows.count
$Excel.Range("A" + $lastrow + 1).Activate()
$ExcelWorksheet.Paste()

adaz fucked around with this message at 00:02 on Dec 10, 2011

Rabid Snake
Aug 6, 2004



adaz posted:

You were really close. There are also some other ways of doing it including using specialCells property on the range interface.

code:
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$ExcelWordBook = $Excel.Workbooks.Open($ExcelPath)
$ExcelWorkSheet = $Excel.WorkSheets.item("sheet1")
$ExcelWorkSheet.activate()


$lastRow = $ExcelWorkSheet.UsedRange.rows.count
$Excel.Range("A" + $lastrow + 1).Activate()
$ExcelWorksheet.Paste()
Appreciate the quick response and help! This works except when it appends, it leaves empty rows between the last piece of data and the appended piece of data. I guess it's including blank cells (that are active, but blank) in it's count. I'm going to try to look into this.

edit: it might be because I have three columns and it's counting all three columns' rows.

edit edit: appreciate the help a lot by the way, was stuck on this for quite some time. Donald Driver is my favorite receiver on the GB receiving corp :3:

Rabid Snake fucked around with this message at 00:20 on Dec 10, 2011

adaz
Mar 7, 2009

Figures. Well looks like we get to use specialCells (http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.specialcells.aspx) anyway! :toot:

code:
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$ExcelWordBook = $Excel.Workbooks.Open($ExcelPath)
$ExcelWorkSheet = $Excel.WorkSheets.item("emailcreate")
$ExcelWorkSheet.activate()

$ExcelWorkSheet.UsedRange.specialCells(11).Activate()
$ExcelWorksheet.Paste()
Any better luck? If it's still having problems it might be because one column is longer than the other and we'll have to dig into the interface to find a way to pull a range object that only includes one column or another way of doing it. Did this real quick before leaving for the day, might want to check into the special cells a bit more, I didn't have time to test

Rabid Snake
Aug 6, 2004



Actually I just figured it out using your first solution! I changed this.
code:
$Excel.Range("A" + $lastrow + 1).Activate()
Say if the last row was A1. By adding that 1 in the end, it'd activate A11. The next last row was A30. It would than activate A301. And it'd go on creating this blank space. I ended up using:

code:
$lastRow = $ExcelWorkSheet.UsedRange.rows.count + 1
$Excel.Range("A" + $lastRow).Select()
$ExcelWorkSheet.Paste()
Thanks very much adaz for the original code!

adaz
Mar 7, 2009

:ughh:

String Formatting will be the death of me. Literally, some guy who screws it up as often as me is going to be in charge of some piece of medical equipment keeping me alive and welp. At least it was something easy and it's working.

wellwhoopdedooo
Nov 23, 2007

Pound Trooper!

adaz posted:

:ughh:

String Formatting will be the death of me. Literally, some guy who screws it up as often as me is going to be in charge of some piece of medical equipment keeping me alive and welp. At least it was something easy and it's working.

I have discovered that there are two types of command interfaces in the world of computing: good interfaces and user interfaces.
-- Daniel J. Bernstein

psylent
Nov 29, 2000

Pillbug
I'm incredibly new to Powershell, as a senior helpdesk monkey I can see how it's going to be incredibly helpful.

I've got a shitload of user accounts (100+) of people that have left the company that I need to clean up/archive. My first step is to move them all into a "To be Terminated" OU. I then need to remove them from all Security/Distribution lists (except Domain Users) - this is where Powershell will come in handy as I'd prefer to run a quick script rather than go into each user and remove the groups manually!

It looks like I need a script that will strip group memberships based on the object's OU. With a bit of Googling, I found this one but am having a bit of trouble deciphering it:
code:
Get-ADGroup -SearchBase "OU=YOUROU,DC=DOMAIN,DC=COM" -Filter* | Foreach-Object{ 
$Members = Get-ADGroupMember -Identity $_ | Where-Object {$_.objectClass -ne 'computer'} 
Remove-ADGroupMember -Identity $_ -Members $Members -Confirm:$true 
} 
Can anyone help me out?

Jelmylicious
Dec 6, 2007
Buy Dr. Quack's miracle juice! Now with patented H-twenty!

psylent posted:

I'm incredibly new to Powershell, as a senior helpdesk monkey I can see how it's going to be incredibly helpful.

I've got a shitload of user accounts (100+) of people that have left the company that I need to clean up/archive. My first step is to move them all into a "To be Terminated" OU. I then need to remove them from all Security/Distribution lists (except Domain Users) - this is where Powershell will come in handy as I'd prefer to run a quick script rather than go into each user and remove the groups manually!

It looks like I need a script that will strip group memberships based on the object's OU. With a bit of Googling, I found this one but am having a bit of trouble deciphering it:
code:
Get-ADGroup -SearchBase "OU=YOUROU,DC=DOMAIN,DC=COM" -Filter* | Foreach-Object{ 
$Members = Get-ADGroupMember -Identity $_ | Where-Object {$_.objectClass -ne 'computer'} 
Remove-ADGroupMember -Identity $_ -Members $Members -Confirm:$true 
} 
Can anyone help me out?

Get-AdGroup will return security groups in a given OU. So this command seems to strip all members of the groups you get, except for computer accounts. I will dissect the command for you later.

What you need, is a command that gets all the users in an OU and then strip their memberships.

psylent
Nov 29, 2000

Pillbug
That's definitely what I need :)

I'll keep looking!

adaz
Mar 7, 2009

I rarely use the powershell AD cmd-lets (I got used to the .NET classes they are based on and just use those), so there is probably an easier one liner for doing this but hey, it works. What we are doing is using Get-ADuser (http://technet.microsoft.com/en-us/library/ee617241.aspx) to retrieve a list of all users in a single OU without any filtering as from what you said that OU just will contain the users we want to delete. After we get the user we iterate through each one and bind to the DirectoryEntry object for that user (http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.aspx) which contains all the useful stuff. This allows us access to the MemberOf attribute for each user. We then use the Remove-ADGroupMember cmd-let to remove the user from each one.

If you want to see what it'll do you can append -whatif to the end of that Remove-AdGroupMember command and it'll go through and list all the users/groups it will remove.

code:
$users = Get-ADUser -filter * -SearchBase "OU=YourDeleteOU,DC=Your,DC=Domain,DC=Com"

foreach($user in $users) {
   $deObj = [ADSI]"LDAP://$($user.distinguishedName)" 
   foreach($group in $deObj.MemberOf) {
       Remove-ADGroupMember -identity $group -members $user.name 
  }
 
}
DO you have like a spreadsheet or text file of the users? You can automate the moving to a different OU as well with that.

adaz fucked around with this message at 07:10 on Dec 19, 2011

evil_bunnY
Apr 2, 2003

psylent posted:

I'm incredibly new to Powershell, as a senior helpdesk monkey I can see how it's going to be incredibly helpful.

I've got a shitload of user accounts (100+) of people that have left the company that I need to clean up/archive. My first step is to move them all into a "To be Terminated" OU. I then need to remove them from all Security/Distribution lists (except Domain Users) - this is where Powershell will come in handy as I'd prefer to run a quick script rather than go into each user and remove the groups manually!


An easier way to do this is to define deny rights on your filesystems and just plop them in that group when they leave (after disabling the account). More work beforehand, but very simple day-to-day.

Wicaeed
Feb 8, 2005
What is the correct way to use a variable that is a command line program in a script?

I'm kind of new so I'll try to make it clearer:

I am trying to run a mysql dump as part of a powershell script. I've defined the following variables:

code:
$mysqldump = "c:\Program Files\MySQL\MySQL Server 5.1\bin\mysqldump.exe"
$sqlServer = 'confluence'
$sqlUser = 'confluence'
$sqlPassword = 'redacted'
$sqlBackupPath = "D:\Scripts\Confluence\Backups\Confluence_MySQL.bkp"
When I go into powershell to test this script, I run it like such:

code:
invoke-expression $mysqldump -u $sqlUser -p$sqlPassword $sqlServer | Out-File $sqlBackupPath 
I get an error message
code:
Invoke-Expression : A positional parameter cannot be found that accepts argument '-u confluence'.
At line:1 char:18
+ invoke-expression <<<<  $mysqldump "-u confluence"
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Expression], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeExpressionCommand 
I assume I'm not correctly passing the arguments for the command line program, but I've tried googling and I can't find out out to do this.

Any tips? Also is this going to behave differently in my script than if I'm running it right from the PowerShell console?

adaz
Mar 7, 2009

When you run the command you need to pass the ENTIRE command to the string. If you are doing - outside the string Powershell thinks those are parameters that are supposed to be passed to Invoke-Command which is why you are getting those errors as Invoke-Command doesn't accept -u or -p.

So the proper way to do it is this long as heck string

code:
$mysqldump = "c:\Program Files\MySQL\MySQL Server 5.1\bin\mysqldump.exe"
$sqlServer = 'confluence'
$sqlUser = 'confluence'
$sqlPassword = 'redacted'

$Command = "$mysqldump -u $sqlUser -p $sqlPassword $sqlServer"

Invoke-Expression -command $command | out-File $SqlBackupPath

Adbot
ADBOT LOVES YOU

Wicaeed
Feb 8, 2005
Aha, that works beautifully. I also decided that adding the C:\Program Files\MySQL\MySQL Server 5.1\bin\ to the script environmental path would be easier to deal with as well:

code:
# MySQL Server Backup Settings
# 
#Define Path for mysqldump.exe
$env:Path = $env:Path + ";C:\Program Files\MySQL\MySQL Server 5.1\bin"
$mysqldb = 'confluence'
$mysqlUser = 'confluence'
$mysqlPassword = 'redacted'
$mysqlBackupPath = "D:\Scripts\Confluence\Backups\Confluence_MySQL.bkp"
$mysqlBackup = "mysqldump.exe -u $mysqlUser -p$mysqlPassword -B $mysqldb"
And it is run with:
code:
 Invoke-Expression -Command $mysqlBackup | Out-File $mysqlBackupPath -Encoding UTF8
Works beautifully :)

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply