mode con: cols=52 lines=16
while ($script -ne "Q") {
$tag = ""
while (-not ($tag)) {
$tag = Read-Host 'Enter tag # or Q to quit'
$date = get-date -f MM-dd-yyyy_HH_mm_ss
$username = [Environment]::Username
if(!(Test-Path -path "C:\Users\$username\Desktop\PSTools\Screenshot Dump\")) {
New-Item "C:\Users\$username\Desktop\PSTools\Screenshot Dump\" -type directory
}
}
if ($tag -eq "Q"){break}
cls
#$ErrorActionPreference = 'silentlycontinue'
cd "C:\Users\$username\Desktop\PSTools"
set-alias psexec "C:\Users\$username\Desktop\PSTools\PsExec.exe"
set-alias nircmd "C:\Users\$username\Desktop\PSTools\nircmd.exe"
------>LOOP START HERE
psexec \\$tag -i -c -s nircmd savescreenshotfull "C:\$tag-$date.png"
move "\\$tag\c$\$tag-$date.png" "C:\Users\$username\Desktop\PSTools\Screenshot Dump\$tag-$date.png"
explorer "C:\Users\$username\Desktop\PSTools\Screenshot Dump\$tag-$date.png"
------>LOOP END HERE
"`n"
}
Basically I'm trying to loop where I have stated above, but I'm use to doing it in command prompt and it's not the same. I want to make it loop X amount of times or until I CTRL+C to quit it.
You could also use a Foreach loop.
Let's say you want to loop 5 times :
$NumberOfLoops = 5
Foreach ($loop in (1..$NumberOfLoops)) { Do Loopy Stuff }
You can use a basic FOR statement to loop. Although, PowerShell has some great looping techniques. It's worth a look through...
http://social.technet.microsoft.com/wiki/contents/articles/4542.powershell-loops.aspx
For an example of a basic FOR loop, just do as so (will loop 10 times ($x=0-9)):
FOR ($x=0; $x -lt 10; $x++) { DO LOOPY STUFF };
Related
How do I create a loop with an iterator that will run the same command that only the counter inside the array will be changed [0] , [1] etc.
Regarding the following code in the "Command Action".
Command = A commands that I running
# Get Results
$rest_api_id = COMMAND --query 'items[*].id' --output text
$CharArray = $rest_api_id.Split()
$CharArray
# Loop Iterator
$Counter_All = For ($i=0; $i -le 10; $i++) {
($i)
}
$Counter_All
# Commands Action
Same COMMAND $CharArray[0]
Same COMMAND $CharArray[1]
Same COMMAND $CharArray[2]
Same COMMAND $CharArray[3]
etc.
Thanks.
I changed the code a little bit and I ended up using the While loop.
$rest_api_id = COMMAND --query 'items[*].id' --output text
$CharArray = $rest_api_id.Split()
$CharArray
$counter = 0
DO
{
CIMMAND $CharArray[$counter]
$counter
$counter++
} While ($counter -le 5)
Thanks.
I am not sure if I understand the question correctly, but I assume you are looking for something like a foreach loop
foreach ($item in $APIArguments) {
& myapicall $item
}
You can look into more details at help about_foreach
I have written a Do..Until statement to check whether a file exists. If the file is not there, it waits a couple seconds and checks again.
It is supposed to end when the file appears. I have tested by running the script without the file and then adding it in the folder as the script is running.
Instead of ending, it continues to loop endlessly. Can anyone see what I have missed?
$path = test-path "C:\Temp\test.txt"
do {
if (!($path)) {
Write-Host "Not here yet..."
Start-Sleep -s 3
}
} until($path)
Write-Host "Files here now"
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
The Test-Path statement is evaluated in the line
$path = Test-Path "C:\Temp\test.txt"
After that the variable $path contains the boolean result of the evaluation. Put the actual check in your conditions:
$path = "C:\Temp\test.txt"
do {
if (-not (Test-Path $path)) {
Write-Host "Not here yet..."
Start-Sleep -s 3
}
} until (Test-Path $path)
or define it as a function that you call in your conditions:
function Test-File {
Test-Path "C:\Temp\test.txt"
}
do {
if (-not (Test-File)) {
Write-Host "Not here yet..."
Start-Sleep -s 3
}
} until (Test-File)
OK, figured it out 3 minutes after posting this (and an hour before that of frustration!).
I needed to put the variable INSIDE the Do..Until statement. Like so:
do{
$path = test-path "C:\Temp\test.txt"
if (!($path))
{Write-Host "Not here yet..."
start-sleep -s 3}
}
until($path)
Write-Host "Files here now"
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
I'm really new to powershell (I've used javascript a bit before), and I was wondering if there's a way to have a powershell script continue running though a loop until a user inputs a specific command to override the loop and break out of it? I've been able to pause the program to wait for a response, but I need the loop to continue running until someone enters a string such as "end." For example, in the following bit of code I wanted to break the while loop and complete a specific command if the user typed "quit," "charger on," or "charger off" at any point.
$overrideProgram = "null"
$overrideProgram = Read-Host
while ($overrideProgram -ne "quit",$overrideProgram -ne "charger on",$overrideProgram -ne "charger off") {
while ($true) {
$chargeLevel = (Get-WmiObject win32_battery).estimatedChargeRemaining #defining the variable "chargeLevel" as the charge percentage
if ($chargeLevel -le 40) {chargerOn}
if ($chargeLevel -ge 80) {chargerOff}
Start-Sleep -s 30 # 30 second delay before next check
}
}
Thanks so much.
Best way I can think to do this is to start a background job and use a script to control the termination of that job:
$job = start-job -scriptblock {
while ($true) {
$chargeLevel = (Get-WmiObject win32_battery).estimatedChargeRemaining #defining the variable "chargeLevel" as the charge percentage
if ($chargeLevel -le 40) {chargerOff}
if ($chargeLevel -ge 80) {chargerOn}
Start-Sleep -s 30 # 30 second delay before next check
}
}
Write-Host "Background job started with id: $($job.id)"
$run = $true
while ($run) {
$op = Read-Host -Prompt "What ya wanna do?"
switch($op) {
"quit" { $run = $false }
"charger on" { $run = $false }
"charger off" { $run = $false }
default { continue }
}
}
stop-job $job.id
receive-job $job.id # If you want to see the output
remove-job $job.id
In the above, a job is started and then your script will just sit in a loop waiting for the correct input. Once it has that, it will exit the loop and proceed to stop and remove the job that was started to begin with.
You will need to extend the contents of the -scriptblock argument of Start-Job to include the chargerOn and chargerOff definitions. If the script is going to be considerably complex, probably best to save it to a file and use the -FilePath argument of Start-Job
The script below asks for the $tag1 variable and uses that, but instead of entering in 1 variable at a time, I want to load a text file with many variables. I know you can use Get-Content c:\scripts\test.txt | Foreach-Object but I am not sure how to use it in this situation.
Get-Content C:\Users\ajstepanik\Desktop\tags.txt | Foreach-Object { write-host $_
#Windows XP
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $tag1)
$key = $reg.OpenSubKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon')
$winxp = $key.GetValue('DefaultUserName') -replace '^.*?\\'
#Windows 7
$reg1 = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $tag1)
$key1 = $reg1.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI')
$win7 = $key1.GetValue('LastLoggedOnUser') -replace '^.*?\\'
set-alias psloggedon 'C:\Users\ajstepanik\Desktop\PSTools\PsLoggedon.exe'
echo "Windows XP"
echo "----------"
echo $winxp
"`n"
echo "Windows 7"
echo "----------"
echo $win7
"`n"
$pstools = psloggedon \\$tag1
echo $pstools
}
I'm not going to attempt to rewrite your script for you, but you need to do something like this:
$fileinput = Get-Content c:\tags.txt
foreach ($tag in $fileinput)
{
Write-Host $tag
# Or whatever it is you're trying to do here
}
I have a folder that should contain 10 files. Each file name will be different (name and extension), however, it will contain a pattern.
eg.
SomeThing.FILE0.DAT
SomeThing.FILE1.DAT
SomeThing.FILE2.DAT
and so on till
SomeThing.FILE9.DAT
My script currently does not have any checks. I manually run it ensuring that all files are present.
for ($i=0; $i -le 9; $i++)
{
$FileString = "*FILE"+$i+"*"
$MyFileName = Get-ChildItem e:\files -name -filter $($FileString)
}
However, I need to automate the process, so I want to add checks to make sure that:
a. Total of 10 files exist in that folder
$FC = ( Get-ChildItem c:\testing | Measure-Object ).Count;
if($FC -eq 10)
{
echo "File Count is correct"
}
else
{
echo "File Count is incorrect"
}
b. Each of the FILEX (X = 0-9) are present
c. Only one instance of each FILEX (X = 0-9) should be present. If multiple instances of FILEX are present, I need to display it on the screen saying that FILEX pattern is repeated multiple times.
How can I do these remaining checks? It looked simple, but is more complicated...
$> if ((compare (ls -name | %{ ([regex]'(?<=.*FILE).*(?=.DAT)').match($_).groups[0].value } | Sort-Object) (0..9 | %{$_.ToString()}) -SyncWindow 0).Length -eq 0) { Write-Host "ok" }
ok
Uh?
Rephrasing your question we have something like "check that directory contains only *FILEX.DAT files, where X should be every possible number between 0 and 9". In powershell it should look something like that:
$> if (allNumbersFromFileNames.IsEqualTo(0..9)) { Write-Info "ok" }
To get all numbers from filenames from the current directory:
$> ls -name | %{ ([regex]'(?<=.*FILE).*(?=.DAT)').match($_).groups[0].value }
0
1
2
3
5
6
7
8
9
4
We've constructed regex here with ([regex]'(?<=.*FILE).*(?=.DAT)') and for every filename in current directory (ls -name | %{ $_ }) parse the magic number in it and get a first matched group's value.
Finally we need to have this string[] object, sort it and compare with array of strings of numbers. compare could be useful here.
I.e.
$> if ((compare 0..9 1..4).Length -eq 0) { Write-Host "equals" }
$> if ((compare 0..9 0..9).Length -eq 0) { Write-Host "equals" }
equals
Put it all together and you have an answer!
Since the regex solution did not work for me, i ended you writing a crude logic. So far it works. If anything better is available, please advise.
for ($i=0; $i -le 9; $i++)
{
$FileString = "*FILE"+$i+"*"
$ct = (Get-ChildItem "C:\testing" -name -filter $($FileString) | Measure-Object ).Count
if($ct -ne 1)
{
if($ct -eq 0)
{
write-host "FILE"$i "is missing"
}
elseif ($ct -gt 1)
{
write-host $ct" instances of FILE"$i" found"
}
else
{
write-host "God help you."
}
}
}