I want to continue my looping. But it does not continue once the first process not found.
This is my code.
function Capture
{
##some process##
Write-Host "Capture"
Start-Sleep -s 1
}
function error
{
##some process##
write-host "error function"
write-host "error function2"
write-host "error function3"
Capture
Exit
}
String = #('The Student Name is','Data Member')
try
{
foreach ($str in $String )
{
$Bio = Get-Content ".\DUMP1.log" -ErrorAction Stop | Where-Object {$_ -like "*$str*"}
if ($null -eq $Bio)
{
Write-Host "not found"
error
continue
}
return $Bio
}
}
catch
{
$msg = "Bio Not Found`n" + $_
$ExitCode = "133"
Exit $ExitCode
}
If the first array not exist in the DUMP.log file, then it stop the process, it does not continue to check the second array.
My expectation is, once the first array can not found, then check the second array, after all the array checking not found, then the process will continue to error function. But The process will not go to error function as long as the process still not checking all the array.
Anyone can help please. Thank you
Related
The below code is designed to check two hard-coded service names (these will never change) and if they are not found to then state the services are not present. It does this but it outputs two lines as there are two services to check.
Is there a way to alter this so that only one output is given after checking both services?
$servicenames = ("Service 1", "Service 2")
Write-Host 'Checking for Services'
function servicevalidation {
foreach ($sn in $servicenames) {
if ((Get-Service "$servicenames*" -Include $servicenames) -eq $null) {
Write-Host 'Young jedi you are mistaken, this server is not a collector!'
} else {
Write-Host "$servicenames present"
}
}
}
Get-Service accepts a list of services, so you can simply do the following without a loop. I would recommend passing the services as an argument, though, if you're encapsulating the check in a function anyway.
function servicevalidation($svc) {
if (Get-Service $svc -ErrorAction SilentlyContinue) {
Write-Host 'Young jedi you are mistaken, this server is not a collector!'
} else {
Write-Host "$svc present."
}
}
servicevalidation $servicenames
The -ErrorAction SilentlyContinue suppresses error output in case a service is not present.
If you want to know which service exactly is missing you could do so with a Where-Object filter:
function servicevalidation($svc) {
$missing = $svc | Where-Object {
-not (Get-Service $_ -ErrorAction SilentlyContinue)
}
if ($missing) {
Write-Host "missing service: $missing"
} else {
Write-Host "$svc present."
}
}
I have an array of servers that I need to loop through, and have an attribute assigned only to specific servers (this happens later in the script).
Here's the array:
$test = #('test_dc','test_fp','test_ts','test_ap')
In the array, I have a domain controller, file/print, terminal server, and application servers (in that order).
The only servers that should get the attribute are the fp, ts, and ap servers.
Here's what I've tried thus far:
foreach ($item in $test) {
Write-Host $item "`n"
Write-Host "Start IF here `n"
if ($item.Name -like '*fp*') {
Write-Host "Found $item"
} else {
Write-Host "ELSE `n"
Write-Host '-=-=-=-=-'
}
}
Here's the output from that:
PS C:\Users\me\Desktop> .\scratch.ps1
test_dc
Start IF here
ELSE
-=-=-=-=-
test_fp
Start IF here
ELSE
-=-=-=-=-
test_ts
Start IF here
ELSE
-=-=-=-=-
test_ap
Start IF here
ELSE
-=-=-=-=-
PS C:\Users\me\Desktop>
According to the way I think it should work, I should see this:
...
test_fp
Found test_fp
...
I've also tried this:
if ($test -contains '*fp') {
Write-Host "Found $_"
} else {
Write-Host 'end'
}
and I just get an empty line.
You're seeing extra info being written to host as you have indefinite writes for each item, regardless if it matches. Since you're including the else statement as well, you're going to see extra stuff written for the non-matched items. Your foreach loop also specifies the name attribute for the object, while your $test array only contains strings.
Here's what I updated it to to limit to only write the host name in your loop if it matches *fp*, otherwise writing your divider:
$test = #('test_dc','test_fp','test_ts','test_ap')
foreach ($item in $test) {
if ($item -like '*fp*') {
Write-Host "Found $item"
} else {
Write-Host '-=-=-=-=-'
}
}
Running that will output this:
-=-=-=-=-
Found test_fp
-=-=-=-=-
-=-=-=-=-
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")
Being new to PowerShell, I have this script which works when using 'switch'. I tried to get it to work using 'while' but it exits whether the value is 1 or 0.
Looking at the script below, could someone point out to me where I am going wrong!!
Your help is appreciated.
cls
Import-Module -Name ActiveDirectory
$ADpath = "OU=OU1,DC=DC1,DC=DC2,DC=DC3";
$i = 0
function yaynay(){
$i = Read-Host "`nSearch again.." "Y `tOR N";
switch -Regex ($i.ToUpper()){
"Y(es)?"{$i -eq 1}
default {$i -eq 0}
}
get-pssession | remove-pssession
}
function TableFormat(){
$x1=#{label='Full Name';Expression={$_.name};width=20},
#{label='Login Name';Expression={$_.samaccountname};width=15},
#{label='OU';Expression={(($_.DistinguishedName -split "=",4)[3] -split ",",2[0]};width=15}
$ADusr | Format-Table $x1
}
function getOut(){
Write-Host "AD Search will now exit"
exit
}
function ADUwrite (){
Write-Output "`n Cannot find user: $InputUsr"
}
while ($i -lt 1)
{
$InputUsr = Read-Host "Enter One or More Letters To Search For User"
$InputUsr1 = $InputUsr
if($InputUsr -eq ""){
write "`n No Search Criteria Entered... Exiting AD User Search"
exit
}
$InputUsr = "*"+$InputUsr+"*"
if([string]$InputUsr1 -contains "*"){
$InputUsr = $InputUsr.Replace($InputUsr, $InputUsr1)
}
$ADusr = Get-ADUser -Filter {name -like $InputUsr} -SearchBase $ADpath
$x=$ADusr.name.length
if($x -gt 0){
TableFormat
}
else{
$InputUsr = $InputUsr1.ToUpper()
ADUwrite $InputUsr
};
yaynay($i)
if($i = 1){
GetOut
}
Get-PSSession | Remove-PSSession
}
Several things here:
function yaynay(){
$i = Read-Host "`nSearch again.." "Y `tOR N";
switch -Regex ($i.ToUpper()){
"Y(es)?"{$i -eq 1}
default {$i -eq 0}
}
get-pssession | remove-pssession
}
The variable $i is local to this function and is never returned so its value won't affect anything happening outside.
yaynay($i)
You don't use parentheses to call a Powershell function (though you do to call a method), it won't matter much here as it will just pass the number 0 as an argument, but if you try it with more than one argument you'll end up passing an array. yaynaydoesn't have any arguments defined so it will ignore the argument anyway.
if($i = 1){
GetOut
}
assigns the value 1 to the variable $i. This is always true so you'll always call GetOut. The comparison should be if ($i -eq 1).
I'm looking for a way to break my Foreach loop.
This is my code
$MyArray = #("desktopstudio","controller","storefront","desktopdirector","licenseserver")
$component = "toto,blabla"
$component = $component.Split(",")
foreach ($value in $component)
{
if ($MyArray -notcontains $value)
{
Write-host "Your parameter doesn't match"
Write-host "Please use one of this parameter $MyArray"
Break
}
}
write-host "I'm here"
I don't understand why it's not breaking my code, because this is the result when I execute it :
Your parameter doesn't match
Please use one of this parameter desktopstudio controller storefront desktopdirector licenseserver
I'm here
You can see that my Write-Host "I'm here" is executed while it should not.
The break statement is used to exit from a loop or switch block which is what it is doing in your case. Instead, you probably want to use the exit command to stop execution of your script when an invalid parameter is found.
$MyArray = #("desktopstudio","controller","storefront","desktopdirector","licenseserver")
$component = "toto,blabla"
$component = $component.Split(",")
foreach ($value in $component)
{
if ($MyArray -notcontains $value)
{
Write-host "Your parameter doesn't match"
Write-host "Please use one of this parameter $MyArray"
exit # <--- change is here
}
}
write-host "I'm here"
See also Get-Help about_Break, Get-Help exit, Get-Help return for more information.