I have the following script.
#Script publicador
$carpetas = Get-ChildItem -Directory -Path C:\Publicaout | Sort-Object {[int]($_ -replace '(\d+).*', '$1')} | Format-Wide -Column 1 -Property Name | Out-String
foreach ($line in $carpetas.Split([string[]]"`r`n", [StringSplitOptions]::RemoveEmptyEntries))
{
$destino = Get-Content c:\Publicaout\$line\Destino.txt
echo $destino
#Copy-Item -Path C:\Publicaout\$line -Recurse -Destination C:\temp\ -ToSession $session -Force
#Invoke-Command -ComputerName $destino -Credential $cred -ScriptBlock {Invoke-Expression -Command:"cmd.exe /c 'c:\temp\$Using:line\publicador.bat'"}
#Invoke-Command -ComputerName $destino -Credential $cred -ScriptBlock {Remove-Item \\$Using:destino\c$\temp\$Using:line -Recurse -Force}
}
What it does, first it sorts by numerical order subfolders on a folder called Publicaout in C:, then I get the list of those subfolders in order, and I use for each to use each element of the list as a parameter, for each one of those folders, I copy it to a remote server, and then I run a script which is located within that copied folder, after that, i delete that folder so i do not leave any leftovers.
So far so good, but now, within each folder there's a text file that contains the destination server that each specific folder must be copied to. So, I believed that adding a Get-Content + path to the file, using the $line variable that contains the subfolder name would be enough, but each time I run the script i get this error:
Get-Content : Cannot find path 'C:\Publicaout\3000\Destino.txt' because it does not exist.
At C:\Users\elmarichaladmin\Documents\publicador.ps1:18 char:14
+ $destino = Get-Content c:\Publicaout\$line\Destino.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Publicaout\3... \Destino.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
This happens with each folder, i have 5 folders, named 1, 99,654,3000, 65404. Its really weird because the Copy command works perfect, but Get-Content does not.
Any ideas? I know that the errors shows an empty line, but as you can see I get rid of each empty line when i run the string split.
Related
I am working on small script to capture file hashes on a running system. I only have Powershell available.
This is the active part of the code:
get-childitem -path $path -filter $filename -Recurse -Force | Select FullName | foreach-object { get-filehash $_.fullname | select * }
this is the command I am testing with:
./Get-FileHashesRecursive.ps1 -path c:\ -filename *.txt
When running the script I get a series of errors because certain folders are inaccessible. I'd like to record the paths of those folders so the user has a record on completion of what failed.
the error looks like this in a console window:
get-childitem : Access to the path 'C:\$Recycle.Bin\S-1-5-21-4167544967-4010527683-3770225279-9182' is denied.
At E:\git\Get-RemoteFileHashesRecursive\Get-FileHashesRecursive.ps1:14 char:9
+ get-childitem -path $path -filter $filename -Recurse -Force | ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\$Recycle.Bin...3770225279-9182:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Is there a way I can grab the path or the entire first line of the error WITHOUT stopping the rest of the script from running?
As requested, here's my earlier comments as an answer:
Get-ChildItem -Path $Path -Filter $Filename -File -Recurse -Force -ErrorVariable FailedItems -ErrorAction SilentlyContinue | ForEach-Object { Get-FileHash -Path $_.FullName | Select-Object * }
$FailedItems | Foreach-Object {$_.CategoryInfo.TargetName} | Out-File "C:\Users\sailingbikeruk\Desktop\noaccess.log"
I have added the -File parameter to Get-ChildItem, because you are specifically dealing with only files.
I also added the -ErrorVariable and -ErrorAction parameters to the Get-ChildItem command. -ErrorVariable FailedItems defines a custom name for a variable which stores errors from the command during processing. -ErrorAction SilentlyContinue, tells the script to continue without notifying you of the errors.
Once your command has finished processing, you can parse the content of the $FailedItems variable. In the example above, I've output the TargetName to a file so that you can read it at your leisure, (please remember to adjust its file path and name as needed, should you also wish to output it to a file).
This Might be an easy one. But I can figure out what is going wrong with my simple copy script.
I have a shared directory that I am copying items from. I am printing out the destination path to console so I know it is correct But I am receiving a powershell error I do not understand.
Here is my script
#Files to copy
#Get Installers from folder
$APPS = Get-ChildItem \\Server1\shared\APPS -Name
#ForEach loop to identify and move files
ForEach($APP in $APPS) {
$dest = "\\Server1\Shared\APPS\$APP"
#Write-host to see destination path on console
write-host $dest
#copy item from destination path to local directory
Copy-Item $dest -Destination "c:\apps\"
}
This seems straight forward. But I don't understand why I am receiving the following error
\\Server1\Shared\APPS\LTCDesktopSetup.exe
Copy-Item : The filename, directory name, or volume label syntax is incorrect.
At C:\Users\computer1\documents\PowerShell\Moving Installer to local drive.ps1:13 char:2
+ Copy-Item $dest -Destination "c:\apps\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
Augusto,
I'd suggest this syntax:
$APPS = (Get-ChildItem "\\mybooklive\CMShared\NAS-Downloads" -filter *.exe).FullName
ForEach ($App in $Apps) {
copy-item "$APP" -Destination "G:\Test\Copy-Test" -Force
}
or the more compact:
$APPS = (Get-ChildItem "\\mybooklive\CMShared\NAS-Downloads" -filter *.exe).FullName |
copy-item -Destination "G:\Test\Copy-Test" -Force
Getting FullName vs Name so you don't have to add the source path back in.
Using -Filter so you only get .exe files (this is an assumption from the variable name $Apps).
The force will take care of some IO problems like the file already existing.
HTH
Naturally, you'll have to substitute your paths for my test ones.
I backed up printers from a Windows 10 system to XML files. I'm trying to add them using the Set-Printconfiguration CMDLET, but it seems to be not accepting variables?
I've looked everywhere but I cannot find anything saying my syntax is wrong.
#get list of printers in backup folder
$printerNames = (Get-ChildItem -Path c:\temp\printers\*.xml -Recurse | select name).name
foreach ($printer in $printerNames)
{
Set-PrintConfiguration -PrinterName $printer -PrintTicketXml c:\temp\printers\$printer
}
Here is the code I used to get the printer XML files:
$TARGETDIR = "c:\temp\printers"
if(!(Test-Path -Path $TARGETDIR )){
New-Item -ItemType directory -Path $TARGETDIR
}
# Get all the printers:
$PN = (get-printer | select name).name
# Foreach loop to create XML file for each printer configuration
Foreach ($P in $PN){
$GPC = get-printconfiguration -PrinterName $P
mkdir c:\temp\printers\$P
$GPC.PrintTicketXML | out-file C:\Temp\printers\$P.xml
# $p|select *|out-file -Path c:\temp\$p.xml -NoTypeInformation
}
edit: here is the error I'm getting:
Set-PrintConfiguration : The specified printer was not found.
At U:\PowerShell\Scripts\backup\newRestorePrinters.ps1:15 char:9
+ Set-PrintConfiguration -PrinterName $printer -PrintTicketXml ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (MSFT_PrinterConfiguration:ROOT/StandardCi...erConfiguration) [Set-PrintConfiguration], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070709,Set-PrintConfiguration
edit
I added more variables to get the list of printers w/out the .XML on the end of the names. It still gives me the same error output. It looks like it's not passing my variables to the set-printconfiguration command?
New restore script code:
$printerShortNameList = (Get-ChildItem -Path c:\temp\printers\*.xml -Recurse | select name).name
foreach ($shortName in $printerShortNameList)
{
$shortName.Replace('.xml', "x")
}
#get list of printers in backup folder
$printerNames = (Get-ChildItem -Path c:\temp\printers\*.xml -Recurse | select name).name
foreach ($printer in $printerNames)
{
Set-PrintConfiguration -PrinterName $shortName -PrintTicketXml c:\temp\printers\$printer
}
What was the error message? Shouldn't you take the '.xml' off the end of $printer for the printer name? I think you have to use add-printer first. I don't believe Set-PrintConfiguration creates printers.
On the bottom when you make the xml files, why do you create the c:\temp\printers\$p directory?
Set-PrintConfiguration:
You need administrator credentials to use Set-PrintConfiguration.
I am trying to execute this code, which just basically copies a file from over the network to the local logged on user's desktop if it is older than the one on the network. The first line of the following code works well, but it throws an error for the part where $env:userprofile is used inside an if block. No idea what's going on here.
Copy-Item -Path "\\path1\subpath1\subpath2\Patch\help\*" -Filter *.chm -Destination "$Env:UserProfile\Desktop" -force -Recurse
$chmfileNetwork = Get-ItemPropertyvalue -Path 'path1\subpath1\subpath2\Patch\help\*' -Filter *.chm -Name 'LastWriteTime'
$chmfileLocal = Get-ItemPropertyValue -Path '$Env:UserProfile\Desktop\*' -Filter *.chm -Name 'LastWriteTime'
if ($chmfileLocal -lt $chmfileNetwork) {
Copy-Item -Path "path1\subpath1\subpath2\Patch\help\*" -Destination "$Env:UserProfile\Desktop" -force -Recurse
} else {
echo "Saul good, man"
}
That throws the error
Get-ItemPropertyValue : Cannot find drive. A drive with the name '$Env'
does not exist.
At C:\Users\user1\Downloads\PS2EXE-GUI\psfile.ps1:28 char:17
+ ... fileLocal = Get-ItemPropertyValue -Path '$Env:UserProfile\Desktop\*' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: ($Env:String) [Get-ItemPropertyValue], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetItemPropertyValueCommand
You can use $home\Desktop to get a user's desktop folder, but Ansgar Wiechers really pointed out the problem with your script as to why it was throwing the error. You used single quotes on the chmfileLocal = line. Variables are not expanded when you use single quotes, only when you use double quotes. The original script could have been fixed with the change of:
$chmfileLocal = Get-ItemPropertyValue -Path "$Env:UserProfile\Desktop\*" -Filter *.chm -Name 'LastWriteTime'
I've got a PS script that looks for the Office15 folder on computers on our network. For the most part, the script works as intended. In fact, this is just me being picky. I set -ErrorAction SilentlyContinue, but the error messages when the Office15 folder is not found still appear on screen. I'm wondering if I'm doing something wrong or just don't really understand what my script is doing.
$filePath = "\\"+$computer+"\c$\Program Files (x86)\Microsoft Office\"
$listing = Get-ChildItem $filePath | where-object { $_.name -eq "Office15" } | Select-Object Name -ErrorAction SilentlyContinue
With this script as-is, I get errors like the following:
Get-ChildItem : Cannot find path '\\COMPNAME\c$\Program Files (x86)\Microsoft Office\' because it does not exist.
At C:\Users\someGuy\bootTime\checkOffice.ps1:16 char:20
+ $listing = Get-ChildItem $filePath | where-object { $_.name -eq "Office1 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\\COMPNAME\c$\Pr...crosoft Office\:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
I pump all of the valid results into a text file, so the other parts of the script work just fine, and I get the expected results otherwise. I'm only really interested in learning what I might be doing wrong here.
You need to pass the error action to gci:
$listing = Get-ChildItem $filePath -ErrorAction SilentlyContinue | where-object { $_.name -eq "Office15" } | Select-Object Name