Search code examples
powershellwinformssyntaxconstructornew-object

Hi this is my PowerShell code I am writing this code to validate IP and add them in a text file


When I run the code I get some error

I am not a PowerShell expert I have referred online documents and code and wrote this code so please help me out

My code :

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Create the form
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "IP Blocking Automation"
$Form.Size = New-Object System.Drawing.Size(400, 400)
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = "FixedDialog"
$Form.MaximizeBox = $False

# Create the xyz label
$LabelTeam = New-Object System.Windows.Forms.Label
$LabelTeam.Text = "xyz"
$LabelTeam.AutoSize = $True
$LabelTeam.Location = New-Object System.Drawing.Point(10, 10)
$LabelTeam.Font = New-Object System.Drawing.Font("Arial", 12, [System.Drawing.FontStyle]::Bold)
$Form.Controls.Add($LabelTeam)

# Create the IP add automation label
$LabelAutomation = New-Object System.Windows.Forms.Label
$LabelAutomation.Text = "IP add automation"
$LabelAutomation.AutoSize = $True
$LabelAutomation.Location = New-Object System.Drawing.Point($Form.ClientSize.Width - $LabelAutomation.PreferredSize.Width - 10, 10)
$LabelAutomation.Font = New-Object System.Drawing.Font("Arial", 12, [System.Drawing.FontStyle]::Bold)
$Form.Controls.Add($LabelAutomation)

# Create the xyz logo picture box
$PictureBox = New-Object System.Windows.Forms.PictureBox
$PictureBox.Image = [System.Drawing.Image]::FromFile("C:\Path\to\xyzLogo.png")
$PictureBox.Size = New-Object System.Drawing.Size(100, 100)
$PictureBox.Location = New-Object System.Drawing.Point(($Form.ClientSize.Width - $PictureBox.Width) / 2, 50)
$Form.Controls.Add($PictureBox)

# Create the input text box
$TextBoxInput = New-Object System.Windows.Forms.TextBox
$TextBoxInput.Multiline = $True
$TextBoxInput.ScrollBars = "Vertical"
$TextBoxInput.Location = New-Object System.Drawing.Point(10, $PictureBox.Bottom + 20)
$TextBoxInput.Size = New-Object System.Drawing.Size($Form.ClientSize.Width - 20, 200)
$Form.Controls.Add($TextBoxInput)

# Create the error label
$LabelError = New-Object System.Windows.Forms.Label
$LabelError.ForeColor = "Red"
$LabelError.AutoSize = $True
$LabelError.Location = New-Object System.Drawing.Point(10, $PictureBox.Bottom + 10)
$Form.Controls.Add($LabelError)

# Create the Add button
$ButtonAdd = New-Object System.Windows.Forms.Button
$ButtonAdd.Text = "Add"
$ButtonAdd.Location = New-Object System.Drawing.Point(($Form.ClientSize.Width - $ButtonAdd.Width) / 2, $LabelError.Bottom + 10)
$Form.Controls.Add($ButtonAdd)

# Function to validate and process the input IP
Function Validate-IP {
    $IP = $TextBoxInput.Text.Trim()

    # Check if IP is in the prohibited subnets
    $ProhibitedSubnets = @("111.112.44.0/24", "111.112.45.0/24")
    $IsProhibited = $ProhibitedSubnets | ForEach-Object { Test-Connection -ComputerName $_ -PingType -Quiet }

    If ($IP -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") {
        If ($IsProhibited) {
            $LabelError.Text = "Cannot add IP from prohibited subnet."
        } ElseIf ($IP -like "10.*" -or $IP -like "172.*" -or $IP -like "192.168.*") {
            $LabelError.Text = "Cannot add private IP."
        } Else {
            $LabelError.Text = ""
            # Process the valid IP (add your code here)
            Write-Host "Valid IP: $IP"

            # Append the valid IP to a text file
            $IP | Out-File -Append -FilePath "C:\Path\to\IPList.txt"
        }
    } Else {
        $LabelError.Text = "Invalid IP format."
    }
}

$ButtonAdd.Add_Click({ Validate-IP })

# Set the form's background color
$Form.BackColor = "LightGray"

# Set the font color for labels and buttons
$LabelTeam.ForeColor = "White"
$LabelAutomation.ForeColor = "White"
$ButtonAdd.ForeColor = "White"

# Set the background color for labels and buttons
$LabelTeam.BackColor = "DarkBlue"
$LabelAutomation.BackColor = "DarkBlue"
$ButtonAdd.BackColor = "DarkBlue"

$Form.ShowDialog() | Out-Null

My error

PS P:\automation\automate IP\using command> . 'P:\automation\automate IP\using command\IP_GUI.ps1'
Method invocation failed because [System.Object[]] does not contain a method named 'op_Subtraction'.
At P:\automation\automate IP\using command\IP_GUI.ps1:24 char:1
+ $LabelAutomation.Location = New-Object System.Drawing.Point($Form.Cli ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Subtraction:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
 
New-Object : Cannot find an overload for "Point" and the argument count: "3".
At P:\automation\automate IP\using command\IP_GUI.ps1:32 char:26
+ ... .Location = New-Object System.Drawing.Point(10, $LabelTeam.Bottom + 2 ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
 
Method invocation failed because [System.Object[]] does not contain a method named 'op_Subtraction'.
At  P:\automation\automate IP\using command\IP_GUI.ps1:33 char:1
+ $TextBoxInput.Size = New-Object System.Drawing.Size($Form.ClientSize. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Subtraction:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
 
Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'.
At  P:\automation\automate IP\using command\IP_GUI.ps1:40 char:1
+ $ButtonAdd.Location = New-Object System.Drawing.Point(($Form.ClientSi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Division:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

I want you to write a PowerShell script that has a GUI good looking and has written in at top left corner xyz

and upper right corner IP blocking automation

and below it should have a big input area where we can only add 1 IP in 1 line without space

It should check IP conditions for each IP and also it should not allow to add IP of subnet 111.112.44.0/24 111.112.45.0/24

Also it should allow to add only public IP not private IP

make the GUI bit colorful and add a xyz logo to it

at the bottom of input field there should be a Add button

Show error above input field

Also when you click on add button try to fill a text file with the valid IP


Solution

  • tl;dr

    Your New-Object syntax was incorrect.

    Use either (applies analogously to all your New-Object calls:

    # New-Object requires *argument syntax*:
    #   Note the (...) around the subtraction only.
    #   The first argument positionally binds to -TypeName,
    #   the second one to -ArgumentList
    New-Object System.Drawing.Point ($Form.ClientSize.Width - $LabelAutomation.PreferredSize.Width - 10), 10
    

    or, preferably, in PSv5+, using the intrinsic static ::new() method that PowerShell exposes on all types for calling constructors, which enables use of true method-call syntax:

    [System.Drawing.Point]::new(
      $Form.ClientSize.Width - $LabelAutomation.PreferredSize.Width - 10, 
      10
    )
    

    As for what you tried:

    New-Object System.Drawing.Point($Form.ClientSize.Width - $LabelAutomation.PreferredSize.Width - 10, 10)
    

    is an example of - unfortunately very common - pseudo method-call syntax, which is best avoided:

    • The (...) part after System.Drawing.Point looks like a list of arguments in a method call, but it isn't; while in practice that often does not matter, in the case at hand it does.

    • Your call is the equivalent of the following New-Object call:

      # !! BROKEN
      New-Object -TypeName System.Drawing.Point `
                 -ArgumentList ($Form.ClientSize.Width - $LabelAutomation.PreferredSize.Width - 10, 10)
      
    • New-Object, as a command (cmdlet) operates in PowerShell's argument[-parsing] mode, i.e. it is invoked like a shell command, with whitespace-separated arguments, with no need for (...) enclosure as a whole.

      • Argument mode has different parsing rules than expression mode, and within expression mode the syntax for the list of arguments in a method call (e.g. .someMethod(..., ...)) is subtly different yet again.

        • See the conceptual about_Parsing help topic for basic information about PowerShell's two fundamental parsing modes.
    • In argument mode - and even in a (...) enclosed expression outside of a method call - , doesn't separate arguments, it acts as , the array constructor ("comma") operator:

      • The , operator has surprisingly high precedence, so that an expression such as 10-5, 2 is parsed as 10 - (5, 2), i.e. an attempt to subtract an array from the number 10 - this results in the error you saw:

        # !! BREAKS, because it is the same as: 10 - (5, 2) 
        Write-Output (10-5, 2)