Need to edit text file in Power Shell - powershell

I am trying to Create a separate script that will edit the file and add the year in the contents. How would I be able to do that
$content ="List of running Services"
$content | out-file C:\Windows\Temp\test
$textfile = get-content C:\Windows\Temp\test
write-host $textfile

Continuing from my comments.
What you need is defined in the Powershell Help files.
Use the Add-Content cmdlet. Use the examples in the Powershell help files
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/add-content?view=powershell-7.1
# Example 1: Add a string to all text files with an exception
Add-Content -Path .\*.txt -Exclude help* -Value 'End of file'
# Example 2: Add a date to the end of the specified files
This example appends the date to files in the current directory and displays the date in the PowerShell console.
Add-Content -Path .\DateTimeFile1.log, .\DateTimeFile2.log -Value (Get-Date) -PassThru
The above examples show how to do things, add strings to a file as well as how to use the date. So, you can extrapolate them both, use Example 2 to get your date info and use example 1 to add the said date to the file contents.

Related

How to Automatically FILL the Fields in Prompt Window pdf to print

I want to convert JPG to PDF without using software packages or LibreOffice.
I use PowerShell, I found the JPG to PDF with MS print to PDF here: https://community.spiceworks.com/topic/2233896-powershell-convert-jpg-to-pdf-using-pdf-printer
but when running, it shows up window that I have to full name of the file manually. I want to autofill that, but haven't found a way. Hope you guys help me.
i used pass thru but no works. Haven't found any yet
If you are just looking for the input file path, then you can alter that in the code by hard-coding your full path in the Get-childitem section. Change the file path to whatever input file path you want along with the file name, you should be good. I have added a comment for your reference on the same line.
$scandir="C:\IT Tools\Print to PDF Powershell\Test-JPG"$scanlogdir="C:\IT Tools\Print to PDF Powershell\Logs"
$pdftoprint=""
$printername= "Nitro PDF Creator (Pro 9)"
#Change the file name and file path of the jpg file # Cleanup old pdf files - Change AddDays value as required
Get-ChildItem "$scanbdir\*.jpg" | ? {LastWriteTime -LT (Get-Date).AddDays(-15)} | Remove-Item -Confirm:$false
# Create a Log file $scanlogname
$scanlogname = Join-Path -Path $scanlogdir -ChildPath "$(Get-Date -Format 'MM-dd-yyyy').log"
# Get the List of files in the Directory
echo "$(get-date) - Checking for any scanned pdf files in $scandir" | Out-File -Append $scanlogname
(Get-WmiObject -ComputerName localhost -Class Win32_Printer -Filter "Name='Nitro PDF Creator (Pro 9)'").setdefaultprinter()
Get-ChildItem -Path $scandir -filter "*.jpg" | % {
Start-Process -FilePath $_.VersionInfo.FileName –Verb print
#out-printer -InputObject $scandir\$pdftoprint $printername
"$(get-date) - Printing file - $_ on Printer - $printername" | Out-File -Append $scanlogname
}

Why does my powershell script loop not work when run, but when stepped through in debugger it works fine?

So I have the below script for a project at work:
# This script will look for a CSV in the script folder
# If found it will split the CSV based on a change in a column header
# It will then create seperate CSV files based on the column data
# get script directory and add it to a variable
Set-Location $PSScriptRoot
$baseDir = $PSScriptRoot
# get a list of csv file names
$csvfile = Get-ChildItem -Path $baseDir -Filter *.csv
# If multiple CSV files loop through all of them
foreach ($i in $csvfile) {
# Import and split the original csv
# Change the value after -Property to match the column header name of the column used to split on value change -
# Header names with spaces require surrounding quotes -
# This value will also be used to name the resulting CSV file
Import-Csv $i | Group-Object -Property "Submission ID" |
Foreach-Object {$path="Output\"+$_.name+".csv" ; $_.group |
Export-Csv -Path $path -NoTypeInformation}
# get the current time and date
$procdte = Get-Date -uformat "%m-%d-%Y %H %M %S"
# rename the original file so that it's not processed again
Rename-Item $i -NewName "Processed $procdte.txt"
}
# End processing loop
Important: some parts of this script are commented out - like the Rename-Item line is half-commented. Dunno why, think it's a stackoverflow markdown issue. It isn't like that in ISE
I tested it out with two csv files in the current directory. It's supposed to rename both files at the end to a .txt so they don't get processed again. When I just run the script, it misses the 2nd csv file. But when I step through it with debugger in ISE, it renames both files fine. What gives?
Ran powershell script, expecting both CSV files to be renamed, however it only renamed one of them. Thought there was an issue with the script, but when I run it in debug, it renames both files fine. Have managed to replicate multiple times.
Edit: to specify - this is not designed to work with two csv files specifically. It's supposed to work with one or more. I was just using two to test.

Powershell: copy file without locking

I created simple nagios plugin check_log.ps1 to check log file on windows machine. It works in way that make copy content of log and in next time look for specified string in difference between copy of log and original log file.
The problem is that sometimes in random moments check_log.ps1 locks log file so it cause stop of the application which create log file.
Generally plugin use original log file in two places
# compare content of $Logfile and $Oldlog, save diff to $tempdiff
Compare-Object -ReferenceObject (Get-Content -Path $Logfile) -DifferenceObject (Get-Content -Path $Oldlog) | Select-Object -Property InputObject > $tempdiff
# override file $Oldlog using conetent of $Logfile
Copy-Item $Logfile $Oldlog
I make test. In one PS session I run while($true) { [string]"test" >> C:\test\test.log }, in second session I run plugin C:\test\check_log.ps1 C:\test\test.log C:\test\Old_log.log test
I'm not fully sure if my test is correct but I think that Copy-Item command cause problem. When I comment this line in script I don't see any errors in terminals. I tested some custom functions to copy file which I found in internet but I din't find solution for my problem.
Do you have an idea how to make it work fully?
if you think the copy-item is locking the file, try reading the content and then saving it to another location. Something like this:
Get-Content $Logfile | Set-Content $Oldlog

PowerShell - check .ini file, log issues

Having trouble with two VNC servers switching off MS Logon Groups being forced. I'm troubleshooting the issue, and one thing I want to do is monitor the config .ini file. I'm relatively new to PowerShell and can't quite get this to work.
Basically, I want the script to check the contents of the configuration file (ultravnc.ini) and see if "MSLogonRequired=1" is a string in that file. If not, I want to append the date to a log file. Eventually I'll do some more with this, but this is my basic need. It's not currently working.
# Variables
$outputFile = "vncMSLogonErrors.txt"
$vncConfig = "C:\Program Files (x86)\uvnc bvba\UltraVNC\ultravnc.ini"
$checkString = "MSLogonRequired=1"
# Get VNC Config File, check for MS Logon setting, write date to file if missing
Get-Content $vncConfig
If (-not $checkString)
{Add-Content $outputFile -Value $(Get-Date)}
Shamus Berube's helpful answer is conceptually simple and works well, if you can assume:
that the line of interest is exactly MSLogonRequired=1, with no variations in whitespace.
that if the INI file is subdivided into multiple sections (e.g, [admin]), that the key name MSLogonRequired is unique among the sections, to prevent false positives.
It is therefore generally preferable to use a dedicated INI-file-parsing command; unfortunately:
PowerShell doesn't come with one, though adding one is being debated
in the meantime you can use the popular PsIni third-party module (see this answer for how to install it and for background information):
Using the PsIni module's Get-IniContent function:
Note: Based on the UltraVNC INI-file documentation, the code assumes that the MSLogonRequired entry is inside the [admin] section of the INI file.
# Variables
$outputFile = "vncMSLogonErrors.txt"
$vncConfig = "C:\Program Files (x86)\uvnc bvba\UltraVNC\ultravnc.ini"
# Check the VNC Config File to see if the [admin] section's 'MSLogonRequired'
# entry, if present, has value '1'.
if ((Get-IniContent $vncConfig).admin.MSLogonRequired -ne '1') {
Add-Content $outputFile -Value (Get-Date)
}
# Variables
$outputFile = "vncMSLogonErrors.txt"
$vncConfig = "C:\Program Files (x86)\uvnc bvba\UltraVNC\ultravnc.ini"
$checkString = "MSLogonRequired=1"
if ((get-content $vncconfig) -notcontains $checkString)) { Add-Content $outputFile -Value $(Get-Date) }

Need to create a script that scans for file names, generates a template for each file and inserts filename into 2 spots within template

Basically what I need is a way to scan a folder for certain files (let's say anything with .xls/xlsx) and generate a text file for each one of those files with a template layout. I figured out how to do this with the script below. However, I need it also to place the filename within the template file as well in 2 locations.
Here is how I have it now.
Get-ChildItem "*PATH*" | Foreach-Object {$_.Name} > C:\Temp\TextGenerate\FileNames.txt
Get-Content C:\Temp\TextGenerate\FileNames.txt | ForEach-Object {
Copy-Item -Path C:\Temp\TextGenerate\FileTemplate.txt -Destination ("C:\Temp\TextGenerate\ListFiles\{0}.txt" -f $_)
}
Basically it scans the folder location, creates a text file (FileNames.txt) with all the file names using a file template file (FileTemplate.txt) and creates one for each file name.
This template (FileTemplate.txt) would be like this:
REPORT-ID=TEST FILE=\\XXXXXXXXXX\XXXXXXXXXX\XXXXXXXXXXX\*insert filename here*, TYPE=XLSX, "SECTION=TEST" TOPIC-ID=TOPIC1, "TOPIC-ITEM=*insert filename here*"
Output would need to be:
REPORT-ID=TEST FILE=\\XXXXXXXXXX\XXXXXXXXXX\XXXXXXXXXXX\filename1.xlsx, TYPE=XLSX, "SECTION=TEST" TOPIC-ID=TOPIC1, "TOPIC-ITEM=filename1.xlsx"
and so on.
Everything on the template would always be the same the only thing that would need to change for each file generated would be the filename for each file found in the folder in the *insert filename here* location.
I am having a problem understand how to insert such things into the file. I would also like if possible to insert the data modified into another line of text in the generated template if possible.
As JosefZ already suggested: read the template file just once, then create the files by filling the template string with values and writing the modified string to the output files.
I would, however, recommend modifying the template to allow using the format operator (-f) on it:
REPORT-ID=TEST FILE=\\XXXXXXXXXX\XXXXXXXXXX\XXXXXXXXXXX\{0}, TYPE=XLSX, "SECTION=TEST" TOPIC-ID=TOPIC1, "TOPIC-ITEM={0}"
Also, there's no need to write the names to a file first. Change your code to something like this:
$template = Get-Content 'C:\Temp\TextGenerate\FileTemplate.txt' | Out-String
Get-ChildItem "*PATH*" | Select-Object -Expand Name | ForEach-Object {
$path = "C:\Temp\TextGenerate\ListFiles\{0}.txt" -f $_
$content = $template -f $_
Set-Content -Path $path -Value $content
}