Why is this PowerShell script constructing unexpected file paths? - variables

Using tips gleaned from this, this, and this, I've finally been able to get a series of file backup scripts going. However, there's one little thing that I've been unable to solve. No runtime errors, but when I run this script,
$originalPath = "\\Server\Path\_testData\"
$backupPath = "\\Server\Path\_backup\"
#
function supportBackup
{
"$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
Get-ChildItem $originalPath\* -Include *.doc*, *.xls*, *.ppt*, *.jpg, *.gif, *.pdf, *.wav, *.avi | `
foreach {
$targetFile = $backupPath + $_.FullName.SubString($originalPath.Length);
New-Item -ItemType File -Path $targetFile -Force;
Copy-Item $_.FullName -destination $targetFile
}
"Support File Backup Completed"
}
supportBackup
The original file path gets dumped into the destination directory instead of just the files.
What I want:
\\Server\Path\_backup\files-from-testData-directory
What I get:
\\Server\Path\_backup\_testData\files-from-testData-directory
I know the problem is closely related (if not identical) to this question, but after studying it and trying to apply some of the wisdom from there, using various iterations of the $_.Name variables, I realize I don't have as good an understanding as I thought I did. I need someone to explain to me HOW the destination path and filename are being constructed with the given variables, and what alternate variables (or code) I need to use to achieve my desired results. There's something that's not clicking for me and I need help understanding it.

You're trying too hard. This should suffice:
$originalPath = '\\Server\Path\_testData'
$backupPath = '\\Server\Path\_backup'
$extensions = *.doc*,*.xls*,*.ppt*,*.jpg,*.gif,*.pdf,*.wav,*.avi
function supportBackup {
"$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
Get-ChildItem "$originalPath\*" -Include $extensions |
Copy-Item -Destination "$backupPath\" -Force
"Support File Backup Completed"
}
supportBackup
You can pipe the results of Get-ChildItem directly into Copy-File. The destination path must end with a backslash, though, otherwise the instruction would try to replace the folder $backupPath with a file of the same name, thus causing an error.

Related

Change Visual Studio project property Start action to "Don't open page" in several projects

When I first download our solution from the version control server, I need to set every project Start action property manually. I would like to know if there is any 'unattended' way to do this. I don't mind creating a batch or powershell script, even opening every needed file and search and replace, assuming this property would be in plain text. I wasn't able to find it in the vbproj file.
In vbproj.user the property is <StartAction>, you must change it's value to NoStartPage.
I ended up putting together a powershell script (based on other answers at stackOverflow) to help me out with that.
gci -r -include "*.vbproj.user" |
foreach-object { $a = $_.fullname; ( get-content $a ) |
foreach-object { $_ -replace "(?<=<StartAction>).*(?=<\/StartAction>)", "NoStartPage" } |
set-content $a }

Changing a string in an .exe file

I would like to know how to change a String in an .exe file. It is a list of 8 files which have all the same Content but are used in diferent paths. And These paths (Folders) are named 1-8. And now I have to Change that string ("word class 1") into 2-8 ("word class 2, ...") I did it manually with Notepad++ for a week now but it's time consuming and I don't want to do it anymore with Notepad++. :)
I don't mind any way of a solution to this Problem so, that's it.
I tried it with powershell so far but I can't figure out how to get the solution done with the get-content & select_string but it didn't work out as intended.
Thank you for reading and answering my question. (sorry for some typos)
You just want to replace some values within a .exe?
This is how I'd do it.
You need to provide a CSV file, first column titled OLD, second column titled new.
Here is my fake .exe file I made:
7deeadc7-a2b3-4c47-8cf6-61f09d986977ham
d1ea8982-4a04-4f2b-8e5a-244965921fccsam
b4a8f37a-c607-405b-8493-9b9b0e79673btam
0922496b-3064-4958-a6b0-46f61a711860turkey
e5f30554-e50e-4b61-aaa3-3797d9e0ed5ccheese
82e3d77f-53d5-49ef-bf84-b872dbbe556ffork
60a01cad-f6c4-44cc-af1a-fafb20377a12rice
e2cd71a1-7c34-456f-9af4-924f79874c38yummy
c85da055-c47e-41be-a0f8-5c320fa05317linux
7dbee5fc-87d5-4900-80c5-00818514d5b4morp
d9941dfe-dd97-422d-9088-2cecf4904fdepoo
05eaf9b3-09a2-45ea-b9a0-4c78ff9156f2pot
8c75d00d-4157-45b9-86df-74226790674fpoe
f0e77eb5-35fa-47f5-b89e-d1b5ef3c726fpoh
1d1ffc02-fee0-446d-aeac-940ab2864a76pof
Just a bunch of guids with a word at the end. Now, Here's my sample .csv file, with all of the replacements we want to make.
OLD,NEW
ham,pork
sam,Frodo
linux,Window
morp,porp
poo,restroom
Finally, here is the code to do this as a PowerShell Function.
Function Refresh-File {
param($inputCSV,$inputfile)
$file = get-content $inputfile
Foreach ($replacement in (Import-csv $inputCSV)){
$file = $file -replace $replacement.old,$replacement.New
}
$file | set-content $inputfile
}
Call it like this: Refresh-File -inputCSV T:\replace.csv -inputfile T:\blah.exe
Here's my .exe file after running this, just the value portions, to show you that it worked:
pork
Frodo
tam
turkey
cheese
fork
rice
yummy
Window
porp
restroom
pot
poe
poh
pof
Since you'll want to automate this, simply make a new replacement.csv file everyday. Then run this code. If you've never written a full PS1 script file before, as a quick summary, copy the function, paste it into notepad or the PowerShell ISE, and then at the last line of the script, put the command syntax to call the function. Save and enjoy.

Powershell to mass rename-move PDFs?

I'm looking to create an automated Powershell script with task scheduler to do a mass rename of auto-generated PDFs and then save them to a second folder. The original name is irrelevant but is generally in the form 0013238974.pdf. These each need to be renamed based on text contained within the file. Example:
TEXT TEXT TEXT
$ACCT_ID
TEXT TEXT TEXT
Thus the new name of the file would need to be $ACCT_ID.pdf, and then saved in the new destination. I've got no problem with the move, that's just a simple
Get-ChildItem -Path C:\Original\PDF\Generation\Folder -Include *.pdf -Recurse |
copy-item -destination C:\The\Folder\I\Need\Them\In
But I'm stumped after that when it comes to extracting the information from the already generated PDF and saving the renamed version as $ACCT_ID.pdf.
I considered running it through a separate PDF print command instead of open/resave, but that doesn't solve my $ACCT_ID extraction problem.
Thanks for any insight on this.
There isn't any build-in functionality for reading PDF files in PowerShell so your best bet is to use a third party .NET component. There are several commercial and also at least a few free open source alternatives.
Here's a few lines of example code using iTextSharp to read the PDF:
Add-Type -Path .\itextsharp.dll
$pdfReader = New-Object iTextSharp.text.pdf.PdfReader("C:\file.pdf")
$textFromFirstPage = [iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdfReader, 1)
$pdfReader.Dispose()
How you go about finding your account id after that of course depends on the text of your files.

Find all files of a given extension when a specific file type exists in another directory

Description
Using Powershell, I am trying to find a list of .vb files that exist in any folder, but only if the bin folder in that directory contains any .compiled file. I will be running this on 1 directory which will contain many folders. The trouble I am having is that the bin folder will not always be at the same depth in the folder structure. I have outlined this with sudo code and examples below. Be sure to see the final result at the very end of the post. Thanks!
Sudo Code
if any '*.compiled' file exists in d:/inetpub/[Unspecified_Number_of_directories]/x/bin
then Find all files recursively in d:/inetpub/[Unspecified_Number_of_directories]/x with extension '*.vb'
Examples
execute directory: d:/inetpub
example 1:
d:/inetpub/123/abc
/bin/
-code.dll
-morecode.dll
-lesscode.compiled
/folder1/
-compiledPage.aspx
-regularPage.aspx
-regularPage.aspx.vb
-anotherPage.aspx
-anotherPage.aspx.vb
/folder2/
-auth.vb
Should result:
d:/inetpub/123/abc/folder1/regularPage.aspx.vb
d:/inetpub/123/abc/folder1/anotherPage.aspx.vb
d:/inetpub/123/abc/folder2/auth.vb
example 2:
d:/inetpub/123/xyz
/bin/
-code.dll
-morecode.dll
-lesscode.dll
/folder1/
-compiledPage.aspx
-regularPage.aspx
-regularPage.aspx.vb
-anotherPage.aspx
-anotherPage.aspx.vb
/folder2/
-auth.vb
Should result:
Nothing
example 3:
d:/inetpub/456
/bin/
-less.compiled
/folder1/
-test.aspx
-test.aspx.vb
/folder2/
-auth.vb
should result:
d:/inetpub/456/folder1/test.aspx.vb
d:/inetpub/456/folder2/auth.vb
Finally
It is important to note that it should be going through all of these examples in one run. I will not be running this script for every folder, but rather the root folder 'd:/inetpub'. So there would be only one list of results that would look like this:
d:/inetpub/123/abc/folder1/regularPage.aspx.vb
d:/inetpub/123/abc/folder1/anotherPage.aspx.vb
d:/inetpub/123/abc/folder2/auth.vb
d:/inetpub/456/folder1/test.aspx.vb
d:/inetpub/456/folder2/auth.vb
I think I'd go a slightly different route than Trevor. Query for the *.compiled files, and when it finds one search that object's directory recursively for *.vb files for each *.compiled file.
GCI D:\inetpub -include *.compiled -recurse|%{GCI "$($_.directory)\.." -include *.vb -recurse|Select FullName}
If that gets you duplicate files (this would happen if you have multiple .compiled files in one folder) you can toss |Select -Unique on the end of that to resolve that issue. It would slow it down though, so I wouldn't do that unless needed.
I tried to edit the script to only include .compiled files located in folders named 'bin' but it failed. Sorry. I did add |Select FullName in there to give a listing more like what you had asked for instead of filesystem objects. Now it just lists full path and filename like you wanted.
I think this should work for you:
$Compiled = Get-ChildItem -Path d:\inetpub\*\x\bin -Include *.compiled -Recurse;
if ($Compiled) {
Get-ChildItem -Path d:\inetpub\*\x -Include *.vb -Recurse;
}

Read Excel .CSV file in Powershell, use a variable from each column, and run a .exe with the variables

I am quite new to Powershell, but I am trying to write what seems like a slightly complicated script. What I am trying to do is read a phone number, a subject, and a file path from the .csv file, put those 3 things as variables, and then run a .exe with the variables. This will be used so we can send faxes to our clients, and there are around 500 or so. I am not sure if this is the easiest way or not to accomplish this with powershell, but the .exe is apparently ready, I just need to see if a powershell script will work in this scenario.
Currently, this is what I have come up with.
$FaxNumber = #()
$Subject = #()
$FilePath = #()
Import-Csv C:\Users\dlappert\Documents\Test\Book1.csv |`
ForEach-Object {
$FaxNumber += $_.FaxNumber
$Subject += $_.Subject
$FilePath += $_.FilePath
}
If ($_.FaxNumber -contains $InputNumber)
{
(*ExecutableFilePath*) /s(FaxServerIpAddress) /u /p /v /o C:\_.log1 /c NO COVER PAGE /r{$_.FaxNumber} /a {$_.FilePath} /b{$_.Subject}
{
I would really appreciate any assistance that anyone could provide with this. This script needs to read the first 3 columns, and execute the script for each row of information. If there is an easier way to accomplish this, please let me know.
As far as I see, you don't need the arrays...
Import-Csv C:\Users\dlappert\Documents\Test\Book1.csv |
foreach {
Start-Process -FilePath "executable_path" -ArgumentList "/s(FaxServerIpAddress) /u /p /v /o C:\_.log1 /c NO COVER PAGE /r$($_.FaxNumber) /a `"$($_.FilePath)`" /b$($_.Subject)"
}
Actually I found an easier way to complete this without Powershell. It seems if we do this with a batch file and convert the .csv file to a text file, it is much easier. Thank you for your assistance though, as we did also get this to work, so if this is an operation that is needed in the future, the powershell script will be ready. I appreciate your assistance Davor.