Error "Cannot find path from" during program start up - powershell

Why is this code not working as was planned?
What is powershell's auto variables for place where the target directory the script is running in?
Set-Location -Path $PSScriptRoot -PassThru
$file1.text="$PSScriptRoot\MIK_Autokontinent.xml
During startup, the program return error cannot find the path from c:\MIK_Autokontinent.xml
but the file is located in c:\program\MIK_Autokontinent.xml
This line is returning the error
$inputpecentw1.Text = [xml](Get-Content $file1.text) | ForEach-Object { $_.SelectNodes(' //FieldCostOptions/IncreaseCost') | ForEach-Object { $_.GetAttribute("Percent") } } | Out-String

You are trying to find the file in your root directory but the program is in the program folder. If your script is in the same folder as the file itself, just use the filename as reference like this $file1.text="MIK_Autokontinent.xml"
But in case you want to do this the way you are doing and from the root folder do it like this $file1.text="$PSScriptRoot\program\MIK_Autokontinent.xml".

Related

How can I execute a command to each file in a directory?

I want to view what's inside each pak of an Unreal Engine 4 game. In the game files there are like 700+ paks, and execute the command to view the content manually it's just a pain.
I'm using Unreal Engine's UnrealPak.exe to view the contents of a pak file.
I use the next command to view (and log) the contents of a pak-
E:\UE_4.10\Engine\Binaries\Win64\UnrealPak.exe (directory of the game)\Content\Paks\(pak file name).pak -test > C:\Users\(user)\Desktop\Logs\log.txt
This will put all the output of that command in the log.txt textfile.
What I want to do is a loop that will execute that command to each file, and then I could do two things, have one log.txt and then put all the outputs of all the paks in there, or have log_(pakname).txt
I could just go manually, but it's going to take a lot of time to execute the same command 700+ times. If someone can help me, I'll be very grateful.
Get-ChildItem -Path. -Recurse -Include "*.pak" | Foreach-Object { invoke-expression "E:\UE_4.10\Engine\Binaries\Win64\UnrealPak.exe $($_.Fullname) -test " | Out-file "log.txt" -Append}
Let's add unrealpak to the path:
$env:path += E:\UE_4.10\Engine\Binaries\Win64
Then
cd somedir\Content\Paks
dir *.pak | foreach { unrealpak $_ -test >> ~\desktop\log.txt }

Copy data for each user using PowerShell

I have a text file with a list of user names separated by semi colon, users names in the text file are: user1; user2; user3, etc.. The user names all have a network folder located at \testserver\users\user1, \testserver\users\user2, and so on.
I am trying to have PowerShell script read the text file and copy the folder and all data in each folder for each user from one location to another location called \testserver\newusers\users. However when I launch the script I have written so far, it just creates a folder with a user name from the text file I have. Below is what I have so far:
$File = Get-Content .\MyFile.txt
$File | ForEach-Object {
$_.Split(';') | ForEach-Object {
Copy-Item -Path "$_" -Destination '\\testserver\newusers\users'
}
}
I am launching my PowerShell .ps1 file from a location that has the myfile.txt file in it.
How do I get this to work properly?
Call Copy-Item with the parameter -Recurse if you want to copy the folders' content as well. Otherwise just the folder itself would be copied (without content). You also need to provide the full path to the source folders unless you run the script from \\testserver\users.
Something like this should work:
$server = 'testserver'
$src = "\\$server\users"
$dst = "\\$server\newusers"
(Get-Content .\MyFile.txt) -split ';' | % {
Copy-Item -Path "$src\$_" -Destination "$dst\" -Recurse
}

Execute Powershell command from script path

First I will give a brief overview of what im trying to achieve. I want to go through a series of HTML files, replace code and then re-save these HTML files. This all works however the PS command will only execute this on HTML files which are on the default Powershell path (for me this is the H drive).
I want to be able to have a seperate folder which contains my powershell script and HTML files and convert them in that folder NOT from the H drive.
The code I have is follows:
Powershell script
$HTMLfiles=get-childitem . *.html -rec
foreach ($files in $HTMLfiles)
{
(Get-Content $files.PSPath) | ForEach-Object { $_ -replace "this text", "TEST" } | Set-Content $files.PSPath
}
This successfully changes all HTML files on the H drive that contain the words 'this text' with 'TEST'. I want to be able to change these HTML files from where the Powershell script is located, NOT from the H drive?
I appreciate any help.
Thanks
Use the built-in variable called $PSScriptRoot to retrieve the files from the same folder where the PowerShell script resides.
Get-ChildItem -Path $PSScriptRoot -Include *.HTML;
In your script, you ask to the Get-ChildItem cmdlet to look for items in the current directory, to make the script look for files in another directory, you just have to specify it to Get-ChildItem :
$HTMLpath="C:\path\to\your\html\files"
$HTMLfiles=get-childitem $HTMLpath *.html -rec
foreach ($files in $HTMLfiles)
{
(Get-Content $files.PSPath) | ForEach-Object { $_ -replace "this text", "TEST" } | Set-Content $files.PSPath
}
Edit :
if you want the path to be passed as an argument to your script, just do the following :
param($HTMLpath)
$HTMLfiles=get-childitem $HTMLpath *.html -rec
foreach ($files in $HTMLfiles)
{
(Get-Content $files.PSPath) | ForEach-Object { $_ -replace "this text", "TEST" } | Set-Content $files.PSPath
}
then you can call your script in the console (assuming you are in the directory where your script is) : ./myscript "C:\path\to\your\files"
Calling Get-ChildItem . *.html -Rec will get all files under the current working directory. If you happen to be in the same folder as your script when you call it, I'd expect it to work as you want. If you call the script from another path, e.g. by setting up a scheduled task to run powershell.exe <path_to_script> then it may not pick up the files you want. Maybe H: is the root of your Windows user profile?
As per other answers, using $PSScriptRoot or passing the path under which the .html files reside in a parameter would be good. To combine both, you can add a parameter to your script AND set the default value for that parameter to be $PSScriptRoot:
param($HTMLpath = $PSScriptRoot)
This will (1) allow you to specify a remote path if necessary and (2) otherwise default to the path where the script is saved.

Read text file and run a copy command for each line in the text file

I am trying to write a Powershell script that will read a text file on my desktop that is filled with user names, then go out to a specified folder on our network share, lets say u:\data and copy the contents from that folder to another network share lets says y:\information, for each user in the text file.
How would this be written?
I have tried several things with reading the text file then trying several commands to copy and paste but they each failed.
UPDATE:
Below is what I have done so far:
$user = Get-Content "test.txt"
$path = "\\abnas2\abusers\users"
$path2 = "\\abnas2\abdept\dept\testcopy"
$Copy = Copy-Item -path $path\$user\ * -Destination $path2\$user
I had one username in the test.txt file called user1 and it pulled the name, and copied perfectly.
Now if I add more than one name to the test.txt file and run the above, it errors out. The error it returned made it look like the 3 user names in the list were one user name.
What I need this to do is run the command for each name on the list. I was thinking I could use the foreach command But not sure how to do it.
UPDATE - 04\09\2014:
I have tried the following and am getting an error back:
$user = Get-Content "test.txt"
$path = "\abnas2\abusers\users"
$path2 = "\abnas2\abdept\dept\testcopy"
$Copy = Copy-Item -path $path\$user* -Destination $path2\$user
foreach($username in $user) {
Copy-Item -path $path\$username* -Destination $path2\$username\
}
When I run it I am getting the following error:
Copy-Item : An object at the specified path \\abnas2\abusers\users\user1 user2 user3 does not exist.
These are the names in my test.txt file, is there a way to get it to read one line at a time and execute the copy and when done go to the next name on the list and do the same? I'm not sure how to get it to do that.
You can use foreach
In this case:
foreach($username in $user) {
Copy-Item -path $path\$username\* -Destination $path2\$username\
}
would copy the contents of each named folder in $user under $path to its corresponding folder in $path2.

Rename first 20 characters of every filename in a file

I am trying to write a script in powershell to remove the first 20 characters of every MP3 filename in a folder, I have created a file 'test.ps' and inserted the powershell code below into it,
gci *.mp3 | rename-item -newname { [string]($_.name).substring(20) }
When I run this file in powershell.exe nothing happens,
Can anyone help? Thanks.
This may get you started. (There are probably much more concise ways, but this works and is readable when you need to maintain it later. :-) )
I created a folder C:\TempFiles, and created the following files in that folder:
TestFile1.txt
TestFile2.txt
TestFile3.txt
TestFile4.txt
(I created them the old-fashioned way, I'm afraid. <g>. I used
for /l %i in (1,1,4) do echo "Testing" > TestFile%i.txt
from an actual command prompt.)
I then opened PowerShell ISE from the start menu, and ran this script. It creates an array ($files), containing only the names of the files, and processes each of them:
cd \TempFiles
$files = gci -name *.txt
foreach ($file in $files) {
$thename = $file.substring(4);
rename-item -path c:\TempFiles\$file -newname $thename
}
This left the folder containing:
File1.Txt
File2.Txt
File3.Txt
File4.Txt
File5.Txt
In order to run a script from the command line, you need to change some default Windows security settings. You can find out about them by using PowerShell ISE's help file (from the menu) and searching for about_scripts or by executing help about_scripts from the ISE prompt. See the sub-section How To Run A Script in the help file (it's much easier to read).
Your code actually works. Two things...
Rename the file to test.ps1.
Run it in the folder you have your MP3 files in. Since you didn't provided a path to Get-ChildItem it will run in the current directory.
I tested your line by making a bunch of mp3 files like this -
1..30 | % { new-item -itemtype file -Name (
$_.ToString().PadLeft(30, 'A') + ".mp3" )}
I would use a more "safer" way (you'll get an error if the file name is shorter than the length in question, you are also targeting the file extension as a part of the total characters). Check if the base name of each file is greater than 21 characters (if you remove the first 20 it can be still have a name with one character long). It can fail if the directory contains a file with same name after you removed the first 20, you can develop it further on your own):
gci *.mp3 | foreach{
if($_.BaseName.Length -ge 21)
{
$ext = $_.Extension
$BaseName = $_.BaseName.Substring(20)
Rename-Item $_ -NewName "$BaseName$ext"
}
}
// delete (replace with empty char) first 20 charters in all filename witch is started with "dbo."
// powershell
Get-ChildItem C:\my_dir\dbo -Recurse -Force -Filter dbo.* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { ($_.name).Substring(20) }