Powershell script: get multiple properties from "Get-Childitem" in a loop - powershell

i am absolutely not a programmer, so please excuse my ignorance and clumsy code.
My task is to change one value per file with 1.25*value in a number of xml-files in a folder.
I have come up with the following code which seems to go through all files and changes each value correctly, then writes the new changed files to a new subfolder "DD1". My test code so far only wrote to a single file test.xml all the time, overwriting it per each loop.
I want the altered files to be named exactly like the original ones, so i am trying to grab each filename within the loop but so far to no avail. Maybe you can tell me, what to put instead of the "????????"
New-Item '.\DD1' -ItemType Directory
Get-ChildItem -Path .\ -Filter *.pws |
Foreach-Object {
[xml]$myXML = Get-Content $_.FullName
$valueString = $myXML.settings.TuningMenu.FF
$valueInt = [int]$valueString
$newValueInt = $valueInt*1.25
$newValueString = [string]$newValueInt
$myXML.settings.TuningMenu.FF = $newValueString
[string]$path = $PWD
[string]$file = ????????
$fullName = $path+"\DD1\"+$file
$myXML.Save("$fullName")
}

Related

How do I get from a csv file only the value of the selected element, but from a different column?

I have this example of csv file:
NAME
PATH
file 1
C:\path1
file 2
C:\path2
file 3
C:\path3
I also have a origin folder which contains files. The idea here is to see if the files in the CSV file exist in the folder and in the destination paths defined in the csv file. If they don't exist, there's nothing to do. If they exist, the script needs to copy them in the path defined in the value PATH of the csv file. So it basically it will rewrite an existing file.
I really hope the definition of the problem is clear. What I have until now is this:
$filesInfo = #(Import-Csv C:\files.csv)
$files = $filesInfo.NAME
$paths = $filesInfo.PATH
foreach ($file in $files){
$isThereOrigin = Test-Path -Path "C:\folder\$file"
if ($isThereOrigin){
foreach ($path in $paths) {
$isThereDestination = Test-Path -Path "$path\$file"
if ($isThereDestination){
Copy-Item -Path "C:\folder\$file" -Destination $path
}
}
}
}
So, basically, what I'm trying to do with this code is that first of all I try to see if the file exists in the origin folder. If there is file there, I see if there's a destination (because it may be the case that the destination file is not there). If both conditions are true, the file is copied. This works correctly.
However, there is a case where this code doesn't work. Let's say the the file2 is contained in path1 and path2. With the code I have now, the file2 is going to be copied in path1 and path2 and I don't want that. I want file2 to be copied only in the path defined in the csv file.
I hope it's clear. Thanks!
Your mistake is in splicing the original array of row-like objects into two separate arrays:
$files = $filesInfo.NAME
$paths = $filesInfo.PATH
Instead, loop over the original $filesInfo array:
foreach ($fileInfo in $filesInfo){
$fileName = $fileInfo.NAME
$isThereOrigin = Test-Path -LiteralPath "C:\folder\$fileName"
if($isThereOrigin){
$path = $fileInfo.PATH
$isThereDestination = Test-Path -LiteralPath "$path\$fileName"
if($isThereDestination){
Copy-Item -LiteralPath "C:\folder\$fileName" -Destination $path -Force
}
}
}

Moving, Encrypting and storing .txt and .pc files to .pgp in PowerShell

I have been learning how to use PowerShell to do some automation that will convert files to a .pgp format. These files end in .txt or .qc. These files are created on one of the servers in the environment, then converted manually, then transferred to another server in the same environment.
I have developed a script that will perform this task, however it will only do one file (I would like for to do all of the files). I the script will not strip the native extension and replace it with only a .pgp extension.
I have included the script below.
PowerShell Script
$_SourcePath = (\\Server1\Location1\*.txt",\\Server1\Location1\*.qc")
$_DestinationPath = "\\Server1\Location2\"
$_SourcePath2 = "\\Server1\Location2\"
$_DestinationPath2 = "\\Server2\Location1\"
Move-item –path $_SourcePath –destination $_DestinationPath
ConvertTo-PgpEncryptedFile -Path "\\Server1\Location2\*.*" -key "\\server3\location1\Enycrption key.asc"
Move-item –path $_SourcePath2 –destination $_DestinationPath2
Again, with this script I can move all the files I need, but it will only encrypt one file and move it to the correct location. I would like for it to encrypt all the files and remove the .txt or .qc extension and replace it with .pgp.
Any Help would be appreciated….
You probably want something along this line:
$SourcePath = '\\Server1\Location1\'
$DestinationPath = '\\Server1\Location2\'
$DestinationPath2 = '\\Server2\Location1\'
$GCIArgs = #{Path = "$($SourcePath)*"
Include = "*.txt","*.qc"
}
$SrcFiles = Get-ChildItem #GCIArgs
ForEach ($File in $SrcFiles) {
Move-item –path "$File.FullName" –destination "$DestinationPath"
$CTPGPArgs =
#{Path = $(Join-Path "$DestinationPath" "$File.Name")
Key = '\\server3\location1\Enycrption key.asc'
}
ConvertTo-PgpEncryptedFile #CTPGPArgs
$EncName = $($_.Name -split('.'))[0] + '.pgp'
$MIArgs = #{Path = "$($CTPGPArgs.Path)"
Destination = $(Join-Path "$DestinationPath2" "$EncName")
}
Move-item #MIArgs
}
I've used single quotes in strings where interpretation is not needed. I've also used splatting to shorten lines and make reading easier.
I eliminated the _ in regular variable names so not to confuse them with items from a pipeline.
Used final Move-Item to also change file extension to .pgp.
Note: I tested as much of this as I could piece-meal but not having servers or the cmdlet ConvertTo-PgpEncryptedFile I couldn't test the entire program.

How to update a zipped file's last write time just after it has been zipped using powershell?

I am very new to Powershell. I have a code that would Zip files from Folder 1 to Folder 2 and update the last Write time of the zipped files to that of the original file.
My code would work in this flow: Zip all the files-->Update all files' last Write Time.
However I want this flow:
Zip 1st file->Update it-->Zip 2nd file-->Update it-->Zip Nth file-->Update it.
I have tried many things. However my code fails while updating just after the file is created. This is the error I get when the update code executes:
Cannot index into a null array.
When I execute the code a second time after all files are created, the code works (Essentially making it flow like I previously mentioned).
Can anyone please have a look at my code and inform if this can be done?
$oldzipfiles = Get-ChildItem $Folder1
$newzipfiles = Get-ChildItem $Folder2
$Files = Get-ChildItem $Folder1
$i = 0;
foreach ($File in $Files) {
#Zipping files
Set-Location $Folder1;
$Zipname = $File.Basename + ".zip";
Zip $Folder2\$Zipname $File;
#Updating LastWriteTime
$newzipfiles[$i].LastWriteTime = $oldzipfiles[$i].LastWriteTime;
$i = $i + 1;
}
Never mind. I found the answer.
$oldzipfiles = Get-ChildItem $Folder1; $newzipfiles = Get-ChildItem $Folder2;
These lines must come inside the foreach loop.. The code works :)

How can I save an XML in a path with 260+ characters?

Here is my situation. I have an XML that resides in a path that contains 260+ characters. One of the folders in this path will always be random, another one is based on versions so it could be different as well.
I am trying to load the XML, make changes to it, and save it back. So far I haven't been able to do that in place so I am copying it to C:\Windows\Temp, making the changes there, and then trying to copy it back in place, which has worked in manual tests.
My main problem is the file path contains more than 260+ characters so Copy-Item hasn't worked properly and I haven't been able to figure out how to get Robocopy to work since I have to use a variable for the path because of the random folders.
XML modification works, copying out to Temp works, the problem I am having is copying it back to the 260+ character path.
I am very new to Powershell as an FYI. Here is what I have come up with so far:
$folderLocation = Get-ChildItem -Path C:\Windows\System32\config\systemprofile\AppData\Local\ProgramA\ -Filter userConfig.xml -Recurse |
Sort-Object LastWriteTime |
Select-Object -last 1 |
Select-Object Directory |
Format-Table -hide
foreach ($f in $folderLocation){
Copy-Item userConfig.xml C:\Windows\Temp
}
$myXML = New-Object System.Xml.XmlDocument
$myXML.Load("C:\Windows\Temp\userConfig.xml")
$isActive = $myXML.SelectSingleNode("//setting[#name = 'Active']")
$isActive.value = "True"
$myXML.Save("C:\Windows\Temp\userConfig.xml")
$convertFolder = [System.String]$folderLocation
Copy-Item ("C:\Windows\Temp\userConfig.xml") $convertFolder
Here is the Robocopy code I tried, I know it's a hackjob but I tried to imitate some things I saw online:
function copy-stuff
{
param([string]$source = "C:\Windows\Temp",
[string]$destination = $convertFolder,
[string]$options = “/R:0″,”/W:0″,”/COPY:DAT”)
[string]$file = "userConfig.xml"
robocopy $source $destination $file $options
}
I tried a couple different things with robocopy but this is what I still had saved. I haven't studied up on creating and using functions in Powershell so this was a monkey see monkey do attempt.
Addressing the Robocopy part of your code:
It looks like you aren't passing anything to your function, but are relying on default values. Try this:
function Copy-Stuff {
param (
[string]$source,
[string]$destination,
[string]$file
)
robocopy $source $destination $file /R:0 /W:0 /COPY:DAT
}
$convertFolder = "blahblah"
Copy-Stuff -Source "C:\Windows\Temp" -Destination $convertFolder -File "userConfig.xml"
If the options never change, then don't bother making them a variable.

Powershell script to extract Cab file contents and move files to new locations

I've been given 14K CAB files each containing 200 files which need to be unzipped into their original locations.
Unfortunately it's not as easy as all of them being extracted to the same location :-(
I've decided to use PowerShell and have generated a list of individual file locations for each file using SQL and can extract the CABs, unfortunately they all extract to the current location.
I am trying to move them to their respective locations, but am struggling.
Here's the code, I've got so far
$shell_app=new-object -com shell.application
$CABfilename= Import-CSV "CABFileList.csv" -Header CABfilename | Foreach-object {
$zip_file = $shell_app.namespace((Get-Location).Path + "\$CABfilename")
$destination = $shell_app.namespace((Get-Location).Path)
$destination.Copyhere($zip_file.items())
$dvs = Import-csv "CABFileList.csv" -Header Path, DVSFilename |
Foreach-object{
Move-item $_.DVSFilename* $_.Path
}
This is an old question, but someone might find the answer useful anyway. I have adapted one I made today to download all WSPs from a farm and extract their contents.
$CABfilename = Import-CSV "CABFileList.csv" -Header CABfilename | Foreach-object {
# Grab the Solution
$Path = $SaveLocation + $CABfilename
# Check the path is ok
$Path
# Make a copy with extension '.cab' for extraction
$DotCab = $CABfilename + ".cab"
$SolutionDir = $Dotcab -replace '.wsp.cab'
mkdir $SolutionDir
copy-item $CABfilename $DotCab
# Now extract it, assuming you have expand.exe in the filsystem (should be in everything post Server 2008 / Vista)
if(C:\Windows\System32\expand.exe) {
try { cmd.exe /c "C:\Windows\System32\expand.exe -F:* $Dotcab $SolutionDir"}
catch { Write-host "Nope, don't have that, soz."}
}}