PowerShell DataGridView checkbox row cell value - winforms

This is the function to check if checkbox is true winforms DataGridView:
function Install {
param (
# OptionalParameters
)
for($i=0;$i -lt $getAppsDataGrid.RowCount;$i++){
if($getAppsDataGrid.Rows[$i].Cells[3].Value -eq $true)
{
$i
$getAppsDataGrid.Rows[$i].Cells[$i].Value
write-host "cell #$i is checked"
#uncheck it
#$datagridview1.Rows[$i].Cells['exp'].Value=$false
}
else
{
#check it
#$datagridview1.Rows[$i].Cells['exp'].Value=$true
write-host "cell #$i is not-checked"
}
}
}
This is working so far. But I want the cell value from the current row. $getAppsDataGrid.Rows[$i].Cells[1].Value is not working in this function. But outside of this function it works. Also other things dont show in here like current var $i. Everything except "cell $i is checked / not checked is" irgnored
Output:
cell #0 is checked
cell #1 is checked
cell #2 is checked
cell #3 is not-checked
cell #4 is not-checked
cell #5 is not-checked
cell #6 is not-checked
cell #7 is not-checked
cell #8 is not-checked
cell #9 is not-checked
cell #10 is not-checked
cell #11 is not-checked

There is a difference between writing something to host and writing it in output (or returning it from function).
When you use Write-output $i or return $i or $i you are adding $i to the output stream, or result of the function. When calling the function if you capture the result in a variable, then the outputs will not print.
Look at this example:
function GetEvens {
for($i=0;$i -lt 10;$i++){
if($i%2 -eq 0)
{
$i
write-host "#$i is even"
}
else
{
write-host "#$i is odd"
}
}
}
$evens = GetEvens
It captures the output (return values) which are even numbers in $evens but write the string "#i is odd" or "#i is even" in host.

Inside your function, you are simply dumping $i and $getAppsDataGrid.Rows[$i].Cells[1].Value through down the pipeline, showing nothing in the console.
To write to console, use the Write-* cmdlets. This is why strings like cell #0 is checked DO show up in the console.
If you want your function to write out everything to the console, change it to something like
function Install {
param (
# OptionalParameters
)
for($i = 0; $i -lt $getAppsDataGrid.RowCount; $i++){
Write-Host "Checking row $i"
if($getAppsDataGrid.Rows[$i].Cells[3].Value) {
Write-Host "Value ($i,$i): {0}" -f $getAppsDataGrid.Rows[$i].Cells[$i].Value
Write-Host "cell #$i is checked"
#uncheck it
#$datagridview1.Rows[$i].Cells['exp'].Value=$false
}
else {
#check it
#$datagridview1.Rows[$i].Cells['exp'].Value=$true
Write-Host "cell #$i is not-checked"
}
}
}

Related

How to show only Read-Host value from a text file array?

I have a text file array JobTitle.txt which looks like this:
Sales Co-Worker, TSALES, TSALSK
Business Navigator, BNOM, BNOMD
And I wanted to write a code that would read the user's input and present the second and the third value from the same line. Here's what I wrote:
$jobtitledb = Get-Content C:\Users\Username\Desktop\Scripts\JobTitle.txt
$jobtitleinput = Read-Host 'Input the job title'
foreach ($data in $jobtitledb) {
$jobtitleinput, $basic, $extended = $data -split ','
Write-Host "Basic template is: "$basic
Write-Host "Extended template is: "$extended
}
I can't seem to figure out how to make it return desired line only. For clarification, when I input Sales Co-Worker I want the program to return:
Basic template is: TSALES
Extended template is: TSALSK
You just need an if statement that checks to make sure your input was the same as the jobtitle its reading in on each line.
$jobtitledb = Get-Content C:\Users\Username\Desktop\Scripts\JobTitle.txt
$jobtitleinput = Read-Host 'Input the job title'
foreach($data in $jobtitledb) {
$jobtitle, $basic, $extended = $data -split ','
If ($jobtitle -eq $jobtitleinput) {
Write-host "Basic template is: "$basic
Write-host "Extended template is: "$extended
}
}
Also I think when you were reading each line you were assigning the jobtitle to the same variable as the user input, so you should change that as well. Above code should work.
Here's an annotated script that should fix your problem. It's mostly the same as the original except where I changed it to store the job tile from the record in $jobtitle instead of $jobtitleinput and added an if statement. Also added a $jobnotfound variable and code to print the appropriate message
$jobtitledb = Get-Content C:\Users\Username\Desktop\Scripts\JobTitle.txt
$jobtitleinput = Read-Host 'Input the job title'
$jobnotfound = $ftrue
foreach($data in $jobtitledb)
{
# Store the job title from the record in $jobtitle instead of
# overwriting $inputjobtitle
$jobtitle, $basic, $extended = $data -split ','
# check the $jobtitle from record against the $jobtitleinput
if ($jobtitle -match $jobinputtitle)
{
Write-host "Basic template is: "$basic
Write-host "Extended template is: "$extended
$jobnotfound = $false
break
}
}
if ($jobnotfound)
{
Write-Host "No job matching '$jobinputtitle' was found."
}
I added an "else" statement, else { Write-Host 'Given job title does
not exist' } But it runs once for each line. How to make it return
only 1 line of "Given job title does not exist"?
I can't post comments yet, however you should just be able to use break within your else statement to exit the foreach loop.
---------- Edit ----------
The following should provide the desired output.
$jobtitledb = Get-Content C:\Users\Username\Desktop\Scripts\JobTitle.txt
$jobtitleinput = Read-Host 'Input the job title'
$found = $false
foreach($data in $jobtitledb)
{
$jobtitle, $basic, $extended = $data -split ','
If ($jobtitle -eq $jobtitleinput) {
Write-host "Basic template is: "$basic
Write-host "Extended template is: "$extended
$found = $true
break
}
}
if(!$found)
{
Write-Host "Given job title does not exist"
}

If-else inside a foreach doesn't return what I think it should

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
-=-=-=-=-
-=-=-=-=-

How to break Foreach loop in Powershell?

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.

Delete elements in an array if they match a value PowerShell

I am parsing a bunch of data in a textfile. I get the data with Get-Content.
Then I loop through each row in $data. Split each row on a space and load those values into an array.
I then loop through each $string in the array.
If the $string matches a specific value I want to delete it out of the array.
$index.Delete(), $index.Remove() does not work, Here is what I have.
$data = Get-Content "C:\Users\$userName\Desktop\test-data.txt"
foreach($row in $data){
if($row)
{
[Array]$index = $row.Split(" ")
$i = 0
foreach($string in $index){
Write-Host $string
if($string -eq "value1" -or $string -eq "value2" -or $string -eq "value3")
{
$index.Delete() //This does not work.
}
}
I have also tried something like this as well but it just was not working out at all.
for($i -eq $index.length; $i -le 0; $i++)
{
Write-Host $index[$i] #this would hit once then give me an error saying the value is null
if($index[$i] -eq "value1" -or $index[$i] -eq "value2" -or $index[$i] -eq "value3")
{
$index.Remove() #does not hit here at all/nor will it work.
Write-Host $index
}
}
How do I remove something from the $index array..?
Is there a better way to do this?
Any help would be much appreciated, thanks.
The easiest way would be to chain -ne operators:
[Array]$index = $row.Split(" ") -ne $value1 -ne $value2 -ne $value3
Each one will remove all the elements of the array that match the value in the variable, and the result will be passed on to the next. When it's finished, the array will contain the elements the didn't match any of the $value variables.
Try this:
[array]$index = $row.Split(" ",[stringSplitOptions]::RemoveEmptyEntries) -notmatch "\b(?:$value1|$value2|$value3)\b"

PowerShell += on foreach loop is adding duplicate instances

I'm using a foreach loop against an array populated by a CSV. The CSV contains lines of product names, current support status, and a version number for when support was started. Sometimes these support versions are comma separated for a variety of reasons.
When a comma-separated version is found in a row, that row is removed from the array. A new row is then created and added to the array for each version found.
The issue I'm having is that if I have a version of "7,8,9" I end up with three rows all listing version 9. Troubleshooting the script shows that the values are being split and picked up correctly, but the array seems to be updating every value with whatever the latest is. For example, the first pass would make version 7, second pass has two instances of v8, last pass ends up with v9 3 times.
How do I make the += operator not update existing rows?
foreach ($line in $sheet)
{
if ($line.'Support Started' -cmatch ",")
{
$sheet = $sheet -ne $line
$line.'Support Started'.Split(",") |
ForEach
{
$subver = $_
$line.'Support Started' = $subver
$sheet = $sheet += ($line)
}
}
}
To provide more info, if I use the following:
write-host $line
$sheet += $line
write-host $line
on a file with 7,8,9 as the version, I get the following output:
Product1,Supported,7
Product1,Supported,7
Product1,Supported,8
Product1,Supported,8
Product1,Supported,9
Product1,Supported,9
When checking the value of $sheet, I get:
Product1,Supported,9
Product1,Supported,9
Product1,Supported,9
Are you sure that you are not reading the file using Import-Csv?
The reason you are having problem is that when you do
foreach ($line in $sheet)
...
then the variable $line is not a copy of the line in $sheet, but a reference to the line in the sheet variable. I.e. when you change $line you are in fact changing $sheet in place.
I would try not to change $sheet while operating on the data, but instead create a new array that can hold all the data. Something like this:
$sheet = Import-Csv data.csv
$newsheet = #()
foreach ($line in $sheet)
{
if ($line.'Support Started' -cmatch ",")
{
$a = $line.'Support Started'.Split(",")
ForEach ($subver in $a)
{
$line2 = $line.PSObject.Copy()
$line2.'Support Started' = $subver
$newsheet += $line2
}
} else {
$newsheet += $line
}
}
$sheet = $sheet += ($line)
$sheet += $line is already appending $line to $sheet. The extra assignment operation is probably causing your issue.
Not tested:
$sheet =
foreach ($line in $sheet)
{
if ($line.'Support Started' -cmatch ",")
{
$line.'Support Started'.Split(",") |
ForEach
{
$subver = $_
$line.'Support Started' = $subver
$line
}
}
else {$line}
}
Your line
$sheet = $sheet += ($line)
should read (edited)
$sheet += #{'product'=$line.product; 'status'=$line.status; 'support started'=$_}
PS gets slightly confused when $line is from $sheet, remedied by making a new object

Resources