Hi I want to create automation script using PowerShell can anyone help me in this ?
Changes for Parent POM.XML: -
I have created below code to update group Id with .eclipse extension in my pom.xml.
for Example, if I consider my group-Id as "hello" I want to replace it by hello.eclipse
$FileContent = Get-ChildItem "C:\Users\Documents\example\pom.xml" | Get-Content $FileContent <# #> $NewFileContent = #() for ($i = 0; $i -lt $FileContent.length; $i++) { if ($FileContent[$i] -like "groupId") { $NewFileContent += ".eclipse" } $NewFileContent += $FileContent[$i] } $NewFileContent | Out-File "C:\Users\Documents\example\pom.xml" Get-ChildItem "C:\Users\Documents\example\pom.xml" | Get-Content
Related
I've been messing with this powershell script (i installed powershell on my mac OS) I also modified the code a bit in the first line.
I am not getting any errors, just nothing happens.
$folder = “/Users/mbp/Desktop/nier_unpacked_2_extracted“
$files = gci -recurse $folder | where { ! $_.PSIsContainer }
$fileContents = $files | foreach { gc -encoding utf8 $_.fullname }
$lines = $fileContents | foreach { if ($_ -match "^JP: (.*)$") { $matches[1] } }
$chars = $lines | foreach { $_.ToCharArray() }
$groups = $chars | group-object
$totals = $groups | sort-object -desc -property count
Basically outputting japanese text characters and how often they show up.
This is the original code(before modification):
$folder = "F:\nier_unpacked_2_extracted"
$files = gci -recurse $folder | where { ! $_.PSIsContainer }
$fileContents = $files | foreach { gc -encoding utf8 $_.fullname }
$lines = $fileContents | foreach { if ($_ -match "^JP: (.*)$") { $matches[1] } }
$chars = $lines | foreach { $_.ToCharArray() }
$groups = $chars | group-object
$totals = $groups | sort-object -desc -property count
Here is the link to the resource i got the code from if that helps: https://dev.to/nyctef/extracting-game-text-from-nier-automata-1gm0
I'm not sure why nothing is returning unfortunately.
In PowerShell (as in most other programming languages), $totals = ... means that you assign the result of the expression at the right side is assigned to the variable ($totals) at the left side.
To display the contents of the variable ($totals), you might use the Write-Output $totals, Write-Host $totals, Out-Defualt $totals, along with a lot of other output cmdlets.
Anyways, in PowerShell, it is generally not necessary to use a cmdlet in instances where the output is displayed by default. For example:
$totals Enter
I am new to powershell scripting and have been tasked to create some alerts based on errors in certain logfiles. These are just logs from a bespoke application.
My current Code is
`$OutputFile3 = (Get-Location).Path + ".\Results.txt"
$Sourcefolder= "C:\Users\dewana\Documents\Test\"
$Targetfolder= "C:\Users\dewana\Documents\Test\Test3"
Get-ChildItem -Path $Sourcefolder -Recurse|
Where-Object {
$_.LastWriteTime -gt [datetime]::Now.AddMinutes(-5)
}| Copy-Item -Destination $Targetfolder
$Testing5 = Get-Content -Tail -1 -Path "C:\Users\dewana\Documents\Test\Test3\*.txt" | Where-Object
{ $_.Contains("errors") }
Remove-Item $OutputFile3
New-Item $OutputFile3 -ItemType file
try
{
$stream = [System.IO.StreamWriter] $OutputFile3
$stream.WriteLine('clientID 1111')
$stream.WriteLine('SEV 1')
$stream.WriteLine('Issue with this process')
}
finally
{
$stream.close()
}`
What i am struggling with is trying is
$Testing5 = Get-Content -Tail -1 -Path "C:\Users\dewana\Documents\Test\Test3\*.txt" | Where-Object { $_.Contains("errors") }
I am trying to store the latest string which contains the word error in the log file. i would want to use the stored string to the create an if statement to say if $Testing5 have a new value of error assigned the create a custom text file.
I can't seem to find out why the get-content is not working with the where-object
The only issue I can see is your Where-Object code block is on the next line.
Get-Content -Tail -1 -Path $tempfile | Where-Object
{ $_.Contains("errors") }
If you separate at the pipe it's fine.
Get-Content -Tail -1 -Path $tempfile |
Where-Object { $_.Contains("errors") }
I'm currently writing a PowerShell script for the first time. I just want to find out which Java versions I have running on my Windows machines. It is searching for all java.exe instants, writes it in a file and then it should execute each line and write the output in a file. But I can't use my variable $command to execute anything. So the for loop is just running one time, because of an error and then quits.
#declaration
$file = ".\text.txt"
$i = 3
$out = ".\output.txt"
Get-ChildItem -Path C:\ -Filter java.exe -Recurse -ErrorAction SilentlyContinue -Force |
Select-Object Directory >> $file
$count = Get-Content $file | Measure-Object -Line
#remove spaces and append "java.exe"
(Get-Content $file | Foreach {$_.TrimEnd()}) | Set-Content $file
(Get-Content $file | foreach {$_ + "\java.exe' -version"}) | Set-Content $file
(Get-Content $file).Replace("C:", "'C:") | Set-Content $file
#remove last 2 lines of the file
$count = $count.Lines - 2
#execute the stored paths
$i = 3
for ($i=3; $i -le $count; $i++) {
$command = Get-Content $file | Select -Index $i;
$command >> $out;
& $command 2> $out; # <----------------This line wont work
echo "_____________________" >> $out;
}
Although I'm not sure what your desired output should look like, but below creates an array of PSObjects that you can output on screen or write to CSV file.
$result = Get-ChildItem -Path C:\ -Filter java.exe -File -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object {
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $_.FullName
$pinfo.Arguments = "-version"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $pinfo
$process.Start() | Out-Null
$process.WaitForExit()
$output = $process.StandardOutput.ReadToEnd()
if (!$output) { $output = $process.StandardError.ReadToEnd() }
[PsCustomObject]#{
'FileName' = $_.FullName
'VersionInfo' = $output
}
}
# output on screen
$result | Format-List
# output to CSV file (VersionInfo field uses multiple lines)
$result | Export-Csv -Path 'D:\javaversions.csv' -UseCulture -NoTypeInformation
Result on screen wil look something like:
FileName : C:\Program Files\Java\jdk1.8.0_31\bin\java.exe
VersionInfo : java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
FileName : C:\Program Files\Java\jdk1.8.0_31\jre\bin\java.exe
VersionInfo : java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
FileName : C:\Program Files\Java\jre1.8.0_221\bin\java.exe
VersionInfo : java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
Your code doesn't work because you're writing entire commandlines to the intermediate file and then try to invoke the command strings from this file via the call operator. That doesn't work because a command "'C:\path\to\java.exe' -version" doesn't exist. You should be getting an error like this:
PS C:\> $command = "'C:\path\to\java.exe' -version"
PS C:\> & $command
& : The term ''C:\path\to\java.exe' -version' is not recognized as the name of
a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
At line:1 char:3
+ & $command
+ ~~~~~~~~
+ CategoryInfo : ObjectNotFound: ('C:\path\to\java.exe' -version:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
The simplest way to make your code work is to just invoke the executables directly:
Get-ChildItem -Path 'C:\' -Filter 'java.exe' -Recurse -EA SilentlyContinue -Force |
ForEach-Object {
$_.FullName + ' -version'
& $_.FullName -version 2>&1
'__________________'
} |
Set-Content $out
If you want to stick with the approach using an intermediate file you need to prepend the commandline with the call operator, convert it to a scriptblock, and then invoke that.
Get-Content $file | ForEach-Object {
$command
& ([Scriptblock]::Create("& $command")) 2>&1
'__________________'
} | Out-File $out
An alternative solution to #Theo is using a temporary file like so:
$GetParams = #{
Path = 'C:\'
Filter = 'java.exe'
Recurse = $true
Force = $true
File = $true
ErrorAction = 'SilentlyContinue'
}
$JavaExeFiles = Get-ChildItem #GetParams | select -First 1
$StartParams = #{
ArgumentList = '-version'
NoNewWindow = $true
RedirectStandardError = '.\javaver.txt'
}
$JaveExeDetails = foreach ($JaveExe in $JavaExeFiles) {
Remove-Item -Path $StartParams.RedirectStandardError -EA Ignore
Start-Process #StartParams -FilePath $JaveExe.FullName -Wait
[PSCustomObject]#{
File = $JaveExe.FullName
Version = Get-Content -Path $StartParams.RedirectStandardError
}
}
# For viewing in the console
$JaveExeDetails | fl *
# For export to a file
$JaveExeDetails | fl * | Out-File -FilePath ./JavaVersions.txt
I've been tasked with creating a script that checks to see if the office cameras we've set up have stopped uploading their feeds to the "Camera" share located on our Windows 2016 storage server. If the NEWEST .mkv is over an hour old compared to the current time (get-date) then the "problem" camera needs to be restarted manually. (No need to script that part.)
Here's what my Director has written so far:
#Variable Definitions start here
$numhours = 1
Get-ChildItem "d:\Shares\Cameras" | Foreach {
$folderToLookAt = ($_.FullName + "\*.mkv")
$result = Get-ChildItem -Recurse $folderToLookAt | Sort-Object CreationTime -Descending
echo $result[0].FullName
echo $result[0].CreationTime
}
The first variable really isn't used yet, but I'm kind of dumb-struck as what to do next. The above returns the full names and creation times successfully of the newest .mkvs
Suggestions on the next part?
Invert the logic - instead of searching all the files, sorting them, finding the most recent, and checking the date, do it the other way round.
Look for files created since the cutoff, and alert if there were none found:
$cutOffTime = [datetime]::Now.AddHours(-1)
Get-ChildItem "d:\Shares\Cameras" | Foreach {
$folderToLookAt = ($_.FullName + "\*.mkv")
$result = Get-ChildItem -Recurse $folderToLookAt | Where-Object { $_.CreationTime -gt $cuttoffTime }
if (-not $result)
{
"$($_.Name) has no files since the cutoff time"
}
}
I'm assuming your paths look like:
D:\Shares\Cameras\Camera1\file1.mkv
D:\Shares\Cameras\Camera1\file2.mkv
D:\Shares\Cameras\Camera2\file1.mkv
D:\Shares\Cameras\Camera2\file2.mkv
D:\Shares\Cameras\Camera3\file1.mkv
.
.
.
If so, I would do something like this:
# The path to your files
$CameraShareRoot = 'D:\Shares\Cameras';
# Number of Hours
$NumberOfHours = 1;
# Date and time of significance. It's $NumberOfHours in the past.
$MinFileAge = (Get-Date).AddHours( - $NumberOfHours);
# Get all the folders at the camera share root
Get-ChildItem -Path $CameraShareRoot -Directory | ForEach-Object {
# Get the most recently created file in each folder
$_ | Get-ChildItem -Recurse -Filter '*.mkv' -File | Sort-Object -Property CreationTime -Descending | Select-Object -First 1
} | Where-Object {
# Remove any files that were created after our datetime
$_.CreationTime -lt $MinFileAge;
} | Select-Object -Property FullName, CreationTime
This will just output the full file name and creation time for stale cameras.
You could do something like this to email yourself a report when the results have any files:
# The path to your files
$CameraShareRoot = 'D:\Shares\Cameras';
# Number of Hours
$NumberOfHours = 1;
# Date and time of significance. It's $NumberOfHours in the past.
$MinFileAge = (Get-Date).AddHours( - $NumberOfHours);
# Get all the folders at the camera share root, save the results to $StaleCameraFiles
$StaleCameraFiles = Get-ChildItem -Path $CameraShareRoot -Directory | ForEach-Object {
# Get the most recently created file in each folder
$_ | Get-ChildItem -Recurse -Filter '*.mkv' -File | Sort-Object -Property CreationTime -Descending | Select-Object -First 1;
} | Where-Object {
# Remove any files that were created after our datetime
$_.CreationTime -lt $MinFileAge;
}
# If there are any stale camera files
if ($StaleCameraFiles) {
# Send an email
$MailMessage = #{
SmtpServer = 'mail.example.com';
To = 'youremail#example.com';
From = 'youremail#example.com';
Subject = 'Stale Camera Files';
Body = $StaleCameraFiles | Select-Object -Property FullName, CreationTime | ConvertTo-Html -Fragment | Out-String;
BodyAsHtml = $true;
}
Send-MailMessage #MailMessage;
}
Generally you will want to use LastWriteTime instead of CreationTime since the latter can be updated by a file move or copy, but maybe that's what you want here.
You have to compare the CreationTime date with (Get-Date).AddHours(-1). The AddHours method allows you to add hours to the DateTime, but also to subtract.
You can use the following example:
$Path = 'd:\Shares\Cameras'
$CreationTime = Get-ChildItem -Path $Path -Filter *.mkv |
Sort-Object -Property CreationTime -Descending |
Select-Object -First 1 -ExpandProperty CreationTime
if ($CreationTime -lt (Get-Date).AddHours(-1)) {
# your action here (restart, send mail, write output, ...)
}
It also optimizes your code a bit. ;)
$LatestFile = Get-ChildItem C:\Users\Connor\Desktop\ | Sort CreationTime | Select -Last 1
if ($LatestFile.CreationTime -gt (Get-Date).AddHours(-1)){
#It's Currently Working
} else {
#Do Other Stuff
}
try this :
Get-ChildItem "c:\temp" -Filter *.mkv -File | sort CreationTime -Descending |
select -First 1 | where CreationTime -lt (Get-Date).AddHours(-1) |
%{Write-Host "Alert !!" -ForegroundColor Red}
I'm working on a script that checks folders in specific directory. For example, I run the script for first time, it generates me a txt file containing folders in the directory.
I need the script to add any new directories that are found to the previously created txt file when the script is run again.
Does anyone have any suggestions how to make that happen?
Here is my code so far:
$LogFolders = Get-ChildItem -Directory mydirectory ;
If (-Not (Test-Path -path "txtfilelocated"))
{
Add-Content txtfilelocated -Value $LogFolders
break;
}else{
$File = Get-Content "txtfilelocatedt"
$File | ForEach-Object {
$_ -match $LogFolders
}
}
$File
something like this?
You can specify what directory to check adding path to get-childitem cmdlet in first line
$a = get-childitem | ? { $_.psiscontainer } | select -expand fullname #for V2.0 and above
$a = get-childitem -Directory | select -expand fullname #for V3.0 and above
if ( test-path .\list.txt )
{
compare-object (gc list.txt) ($a) -PassThru | Add-Content .\list.txt
}
else
{
$a | set-content .\list.txt
}