I am currently trying to use the values of a date/time picker variable from one function and use it multiple times in another function. The date/time picker is on a form, so when a user sets a start date and end date, those values are assigned to a variable to use in the other function, which should call both those variables at least twice. While trying to call that variable from the first function, it contains a null value even though it was assigned to a variable. I am trying to keep the value that was created in one function to use in another function multiple times. Thank you.
Set-strictMode -off
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
[System.Windows.Forms.Application]::EnableVisualStyles()
Add-Type -AssemblyName System.Web
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
$global:startDate=$null
$global:endDate=$null
function MakeForm{
#region begin GUI
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '396,180'
$Form.text = "Rexpii Integrations Version (Beta)"
$Form.BackColor = "#ffffff"
$Form.TopMost = $False
$Form.Icon= [System.Drawing.Icon]::ExtractAssociatedIcon('C:\files\scripts\tpgicon.ico')
$btnSubmit = New-Object system.Windows.Forms.Button
$btnSubmit.text = "Submit"
$btnSubmit.width = 60
$btnSubmit.height = 30
$btnSubmit.location = New-Object System.Drawing.Point(220,116)
$btnSubmit.Font = 'Microsoft Sans Serif,10'
$btnSubmit.Add_Click({
$global:startDate= $Global:txtStartDate.Value.ToString("yyyy-MM-dd")
$global:endDate= $Global:txtEndDate.Value.ToString("yyyy-MM-dd")
GetData
$Form.Close()})
$btnCancel = New-Object system.Windows.Forms.Button
$btnCancel.text = "Cancel"
$btnCancel.width = 60
$btnCancel.height = 30
$btnCancel.location = New-Object System.Drawing.Point(288,116)
$btnCancel.Font = 'Microsoft Sans Serif,10'
$btnCancel.Add_Click({
$Form.Close()
})
$Global:txtStartDate = New-Object system.Windows.Forms.DateTimePicker
$Global:txtStartDate.width = 150
$Global:txtStartDate.location = New-Object System.Drawing.Point(208,40)
$Global:txtStartDate.Format = "Custom"
$Global:txtstartDate.CustomFormat = "yyyy-MM-dd"
$Global:txtEndDate = New-Object system.Windows.Forms.DateTimePicker
$Global:txtEndDate.width = 150
$Global:txtEndDate.location = New-Object System.Drawing.Point(208,80)
$Global:txtEndDate.Format="Custom"
$Global:txtEndDate.CustomFormat = "yyyy-MM-dd"
$Form.controls.AddRange(#($btnSubmit,$btnCancel,$PictureBox1,$PictureBox2,$StartDate,$EndDate,$lblStartDate,$lblEndDate,$txtStartDate, $txtEndDate))
[void]$Form.ShowDialog()
}
MakeForm
function GetData{
#my scripts number one
Write-Output "This is the first $global:startDate to $global:endDate example"
#my scripts number two
Write-Output "This is the second $global:startDate to $global:endDate example"
}
First, you need to define your functions before you can use them. You are trying to call GetData before it's defined. Move the call to MakeForm (which also shows the form) to after the function definition for GetData.
Second, should change GetData to call Write-Host instead of Write-Output so you can see the output from the event handler. And if you call GetData after showing the form, you'll see that the globals are set properly.
So the last part of your script should look like:
function GetData{
#my scripts number one
Write-Host "This is the first $global:startDate to $global:endDate example"
#my scripts number two
Write-Host "This is the second $global:startDate to $global:endDate example"
}
MakeForm
# Call GetData again to verify that the globals are set.
GetData
Related
The text is an html file. The line I am interested in looks something like:
<td>INC1234</td><td>INC1235</td><td>INC1236</td>
The INC numbers are different from file to file. I'd like to parse through the line by saying something like:
if like <td>INC, then concatenate '<td><a href="https://www.website.com/=' + INC# + '>"
To give an output like:
<td><a href="https://www.website.com/=INC1234>INC1234</a></td><td><a href="https://www.website.com/=INC1235>INC1235</a></td><td><a href="https://www.website.com/=INC1236>INC1236</a></td>"
EDIT1: Ok, if I do something like:
$parse = (-split (Get-Content -Raw C:\Temp\report.txt) -match '<td>INC')
$parse
It will find the characters, but it will return the entire line rather than looking for more that match the 'INC'. Presumably because they all reside on the same line with no spaces.
EDIT2: Maybe this will help. What I'm doing is using PowerShell to write SQL commands, send it to our SQL Server, return the data and use PSWriteHTML to build the report which works fantastic. But I am wanting the first column, which is the ticket number (eg. INC1234) to be a link to the ticket it reads.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$ReportName
)
## Build the query box
function Read-MultiLineInputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
## Create the Label.
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Size(10,10)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.AutoSize = $true
$label.Text = $Message
## Create the TextBox used to capture the user's text.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Size(10,40)
$textBox.Size = New-Object System.Drawing.Size(575,200)
$textBox.AcceptsReturn = $true
$textBox.AcceptsTab = $false
$textBox.Multiline = $true
$textBox.ScrollBars = 'Both'
$textBox.Text = $DefaultText
## Create the OK button.
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Size(415,250)
$okButton.Size = New-Object System.Drawing.Size(75,25)
$okButton.Text = "OK"
$okButton.Add_Click({ $form.Tag = $textBox.Text; $form.Close() })
## Create the Cancel button.
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(510,250)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Cancel"
$cancelButton.Add_Click({ $form.Tag = $null; $form.Close() })
## Create the form.
$form = New-Object System.Windows.Forms.Form
$form.Text = $WindowTitle
$form.Size = New-Object System.Drawing.Size(610,320)
$form.FormBorderStyle = 'FixedSingle'
$form.StartPosition = "CenterScreen"
$form.AutoSizeMode = 'GrowAndShrink'
$form.Topmost = $True
$form.AcceptButton = $okButton
$form.CancelButton = $cancelButton
$form.ShowInTaskbar = $true
## Add all of the controls to the form.
$form.Controls.Add($label)
$form.Controls.Add($textBox)
$form.Controls.Add($okButton)
$form.Controls.Add($cancelButton)
## Initialize and show the form.
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() > $null # Trash the text of the button that was clicked.
## Return the text that the user entered.
return $form.Tag
}
## Prompt the SQL Query Box
$Query = Read-MultiLineInputBoxDialog -Message "Enter SQL Query Here" -WindowTitle "SQL Query" -DefaultText "SELECT FROM"
if ($Query -eq $null) { Break }
else { Write-Host "You entered the following text: $Query" }
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
## Output the report and save to the network under the specified name
New-HTML {
New-HTMLTable -EnableColumnReorder -DisableInfo -DataTable $Pass -ExcludeProperty "RowError", "RowState", "Table", `
"ItemArray", "HasErrors" -HideFooter -PagingLength 25 -SearchBuilder
New-HTMLTableStyle -FontFamily Calibri -FontSize 15 -FontStyle normal -TextAlign center -TextColor "#0a0a0a"
New-HTMLTableStyle -FontFamily Calibri -BackgroundColor "#fffdb5" -FontSize 15px -TextColor "#0a0a0a" -TextAlign center -Type RowHover
} -ShowHTML -FilePath "\\Server\$ReportName.html" -Online
The report looks something like:
Ticket: Description:
----------------------------
INC1234 Broken Monitor
INC1235 No Sound
The HTML that PSWriteHTML builds throws all of the ticket numbers on one line so I would like to edit that HTML with the <a href=""> tag to dynamically create links for each ticket # mainly because I don't know how to do it in PS and can't seem to find a good answer through Google - which is why I came here.
Although not familiar with PsWriteHtml, I guess you could simply change the Ticket properties in the array you receive in $Pass:
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
# convert all Tickets into hyperlinks
foreach ($item in $Pass) {
$item.Ticket = '<a href="https://www.website.com/={0}>{0}</a>'-f $item.Ticket
}
Then the rest of your code
## Output the report and save to the network under the specified name
New-HTML {...}
I want to run a defined PowerShell function on an add_click event in a Windows form in that script.
I've found lots of examples of how to call a .ps1 script from a click, but not how to call a function.
Use powershell command in add_click
So, here is my script in full. I am curious on two ways of outputting this information.
• Just open a PowerShell console and show the results in there (the pause will prevent it from closing), or
• In some kind of MessageBox (some more Windows Forms magic or techniques or tooltips, or whatever anyone thinks works well - such techniques are all very interesting to me).
function sysx {
$System = get-wmiobject -class "Win32_ComputerSystem"
$Mem = [math]::Ceiling($System.TotalPhysicalMemory / 1024 / 1024 / 1024)
$wmi = gwmi -class Win32_OperatingSystem -computer "."
$LBTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)
[TimeSpan]$uptime = New-TimeSpan $LBTime $(get-date)
$s = "" ; if ($uptime.Days -ne 1) {$s = "s"}
$uptime_string = "$($uptime.days) day$s $($uptime.hours) hr $($uptime.minutes) min $($uptime.seconds) sec"
"$Mem GB"
"Up: $uptime_string"
pause
}
# Load Assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationFramework # For MessageBox
$MyIcon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)
# Create Primary form
$objForm = New-Object System.Windows.Forms.Form
$objForm.Visible = $false
$objForm.WindowState = "minimized"
$objForm.ShowInTaskbar = $false
$objForm.add_Closing({ $objForm.ShowInTaskBar = $False })
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = $MyIcon
$objNotifyIcon.Text = "TrayUtility"
$objNotifyIcon.Visible = $true
$objContextMenu = New-Object System.Windows.Forms.ContextMenu
$ToggleMenuItemPS = New-Object System.Windows.Forms.MenuItem
$ToggleMenuItemPS.Index = 1
$ToggleMenuItemPS.Text = "New PowerShell"
if (Test-Administrator) { $ToggleMenuItemPS.Text = "New PowerShell (Admin)" }
$ToggleMenuItemPS.add_Click({
Start-Process PowerShell.exe
})
$ToggleMenuItemFunction = New-Object System.Windows.Forms.MenuItem
$ToggleMenuItemFunction.Index = 2
$ToggleMenuItemFunction.Text = "Mem and Uptime"
$ToggleMenuItemFunction.add_Click({
# some way to call the 'sysx' function in a PowerShell console, MessageBox, tooltip, etc...
})
# Create an Exit Menu Item
$ExitMenuItem = New-Object System.Windows.Forms.MenuItem
$ExitMenuItem.Index = 5
$ExitMenuItem.Text = "E&xit"
$ExitMenuItem.add_Click({
$objForm.Close()
$objNotifyIcon.visible = $false
})
# Add the Menu Items to the Context Menu
$objContextMenu.MenuItems.Add($ToggleMenuItemPS) | Out-Null
$objContextMenu.MenuItems.Add($ToggleMenuItemFunction) | Out-Null
$objContextMenu.MenuItems.Add($ExitMenuItem) | Out-Null
# Assign the Context Menu
$objNotifyIcon.ContextMenu = $objContextMenu
$objForm.ContextMenu = $objContextMenu
# Show the Form - Keep it open
$objForm.ShowDialog() | Out-Null
$objForm.Dispose()
You can just use only sysx there:
$ToggleMenuItemFunction.add_Click({sysx})
To show results in a message box tweak sysx a bit:
$wshshell = new-object -comobject Wscript.shell
$wsh.PopUp("$($Mem) GB`nUp: $($uptime_string)")
All code has scope, even for output. Your function will run, but since you are note telling the output where to go. I added the Test admin function since it was left out of your post.
I tested and validated the below and it works on my system, in a running PowerShell console/ISE/VSCode session. Meaning, it prints this output to the console (of course you can change that to send to a Message Box, et al) and start a new console as admin.
#region Begin code-behind logic
#
function Test-Administrator
{
([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::
GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
}
function Get-Sysx {
$System = get-wmiobject -class "Win32_ComputerSystem"
$Mem = [math]::Ceiling($System.TotalPhysicalMemory / 1024 / 1024 / 1024)
$wmi = gwmi -class Win32_OperatingSystem -computer "."
$LBTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)
[TimeSpan]$uptime = New-TimeSpan $LBTime $(get-date)
$s = ""
if ($uptime.Days -ne 1) {$s = "s"}
$uptime_string = "$($uptime.days) day$s $($uptime.hours) hr $($uptime.minutes) min $($uptime.seconds) sec"
"$Mem GB"
"Up: $uptime_string"
pause
}
#
#endregion End code behind logic
#region Begin GUI logic
#
# Load Assemblies
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationFramework # For MessageBox
$MyIcon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)
# Create Primary form
$objForm = New-Object System.Windows.Forms.Form
$objForm.Visible = $false
$objForm.WindowState = "minimized"
$objForm.ShowInTaskbar = $false
$objForm.add_Closing({ $objForm.ShowInTaskBar = $False })
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = $MyIcon
$objNotifyIcon.Text = "TrayUtility"
$objNotifyIcon.Visible = $true
$objContextMenu = New-Object System.Windows.Forms.ContextMenu
$ToggleMenuItemPS = New-Object System.Windows.Forms.MenuItem
$ToggleMenuItemPS.Index = 1
$ToggleMenuItemPS.Text = "New PowerShell"
if (Test-Administrator) { $ToggleMenuItemPS.Text = "New PowerShell (Admin)" }
$ToggleMenuItemPS.add_Click({
Start-Process PowerShell.exe
})
$ToggleMenuItemFunction = New-Object System.Windows.Forms.MenuItem
$ToggleMenuItemFunction.Index = 2
$ToggleMenuItemFunction.Text = "Mem and Uptime"
$ToggleMenuItemFunction.add_Click({
Get-Sysx | Out-Host
})
# Create an Exit Menu Item
$ExitMenuItem = New-Object System.Windows.Forms.MenuItem
$ExitMenuItem.Index = 5
$ExitMenuItem.Text = "E&xit"
$ExitMenuItem.add_Click({
$objForm.Close()
$objNotifyIcon.visible = $false
})
# Add the Menu Items to the Context Menu
[void]$objContextMenu.MenuItems.Add($ToggleMenuItemPS)
[void]$objContextMenu.MenuItems.Add($ToggleMenuItemFunction)
[void]$objContextMenu.MenuItems.Add($ExitMenuItem)
# Assign the Context Menu
$objNotifyIcon.ContextMenu = $objContextMenu
$objForm.ContextMenu = $objContextMenu
#endregaion End GUI logic
# Show the Form - Keep it open
[void]$objForm.ShowDialog()
$objForm.Dispose()
As for this... [I was hopeful that would work, but using Get-Sysx on its own does nothing.], if you are saying you are not in a PowerShell session when you call this, then that is because you did not start one before the call, so, nothing to write to. So, call a message box instead and the separate call to powershell.exe, and that pause is not needed since the messagebox will stay shown until dismissed.
$ToggleMenuItemFunction = New-Object System.Windows.Forms.MenuItem
$ToggleMenuItemFunction.Index = 2
$ToggleMenuItemFunction.Text = "Mem and Uptime"
$ToggleMenuItemFunction.add_Click({
[System.Windows.Forms.MessageBox]::Show($(Get-Sysx), 'Information', 0)
})
I have a script, which creates a GUI to put in parameters to create an AD user. The script contains a large function (one that creates a AD browser that I found on the net). The function is called right at the start of the script (one textbox requires input from the function to prefill a value) or by clicking a button in the GUI. Problem is, that when I run the script, I get error message saying, that "The term 'Browse-AD' (=name of the function) is not recognised as the name of a cmdlet, function..." When I run it from PowerShell ISE, I get this error for the first time I try, the script launches (but the browser doesn't work) and after cancelling the script and running it again the browser works fine, no error message is displayed. I didn't touch the script in the mean time, I just run it for the second time, no changes made. But the bigger problem is, that when the script is launched from a file directly (which is naturally its intended way of usage), it's always the first attempt and therefore the error is always displayed and browser doesn't work. Any idea what's happening?
This is the function:
function Browse-AD()
{
# original inspiration: https://itmicah.wordpress.com/2013/10/29/active-directory-ou-picker-in-powershell/
# author: Rene Horn the.rhorn#gmail.com
<#
Copyright (c) 2015, Rene Horn
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>
$dc_hash = #{}
$selected_ou = $null
Import-Module ActiveDirectory
$forest = Get-ADForest
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
function Get-NodeInfo($sender, $dn_textbox)
{
$selected_node = $sender.Node
$dn_textbox.Text = $selected_node.Name
}
function Add-ChildNodes($sender)
{
$expanded_node = $sender.Node
if ($expanded_node.Name -eq "root") {
return
}
$expanded_node.Nodes.Clear() | Out-Null
$dc_hostname = $dc_hash[$($expanded_node.Name -replace '(OU=[^,]+,)*((DC=\w+,?)+)','$2')]
$child_OUs = Get-ADObject -Server $dc_hostname -Filter 'ObjectClass -eq "organizationalUnit" -or ObjectClass -eq "container"' -SearchScope OneLevel -SearchBase $expanded_node.Name
if($child_OUs -eq $null) {
$sender.Cancel = $true
} else {
foreach($ou in $child_OUs) {
$ou_node = New-Object Windows.Forms.TreeNode
$ou_node.Text = $ou.Name
$ou_node.Name = $ou.DistinguishedName
$ou_node.Nodes.Add('') | Out-Null
$expanded_node.Nodes.Add($ou_node) | Out-Null
}
}
}
function Add-ForestNodes($forest, [ref]$dc_hash)
{
$ad_root_node = New-Object Windows.Forms.TreeNode
$ad_root_node.Text = $forest.RootDomain
$ad_root_node.Name = "root"
$ad_root_node.Expand()
$i = 1
foreach ($ad_domain in $forest.Domains) {
Write-Progress -Activity "Querying AD forest for domains and hostnames..." -Status $ad_domain -PercentComplete ($i++ / $forest.Domains.Count * 100)
$dc = Get-ADDomainController -Server $ad_domain
$dn = $dc.DefaultPartition
$dc_hash.Value.Add($dn, $dc.Hostname)
$dc_node = New-Object Windows.Forms.TreeNode
$dc_node.Name = $dn
$dc_node.Text = $dc.Domain
$dc_node.Nodes.Add("") | Out-Null
$ad_root_node.Nodes.Add($dc_node) | Out-Null
}
return $ad_root_node
}
$main_dlg_box = New-Object System.Windows.Forms.Form
$main_dlg_box.ClientSize = New-Object System.Drawing.Size(400,600)
$main_dlg_box.MaximizeBox = $false
$main_dlg_box.MinimizeBox = $false
$main_dlg_box.FormBorderStyle = 'FixedSingle'
# widget size and location variables
$ctrl_width_col = $main_dlg_box.ClientSize.Width/20
$ctrl_height_row = $main_dlg_box.ClientSize.Height/15
$max_ctrl_width = $main_dlg_box.ClientSize.Width - $ctrl_width_col*2
$max_ctrl_height = $main_dlg_box.ClientSize.Height - $ctrl_height_row
$right_edge_x = $max_ctrl_width
$left_edge_x = $ctrl_width_col
$bottom_edge_y = $max_ctrl_height
$top_edge_y = $ctrl_height_row
# setup text box showing the distinguished name of the currently selected node
$dn_text_box = New-Object System.Windows.Forms.TextBox
# can not set the height for a single line text box, that's controlled by the font being used
$dn_text_box.Width = (14 * $ctrl_width_col)
$dn_text_box.Location = New-Object System.Drawing.Point($left_edge_x, ($bottom_edge_y - $dn_text_box.Height))
$main_dlg_box.Controls.Add($dn_text_box)
# /text box for dN
# setup Ok button
$ok_button = New-Object System.Windows.Forms.Button
$ok_button.Size = New-Object System.Drawing.Size(($ctrl_width_col * 2), $dn_text_box.Height)
$ok_button.Location = New-Object System.Drawing.Point(($right_edge_x - $ok_button.Width), ($bottom_edge_y - $ok_button.Height))
$ok_button.Text = "Ok"
$ok_button.DialogResult = 'OK'
$main_dlg_box.Controls.Add($ok_button)
# /Ok button
# setup tree selector showing the domains
$ad_tree_view = New-Object System.Windows.Forms.TreeView
$ad_tree_view.Size = New-Object System.Drawing.Size($max_ctrl_width, ($max_ctrl_height - $dn_text_box.Height - $ctrl_height_row*1.5))
$ad_tree_view.Location = New-Object System.Drawing.Point($left_edge_x, $top_edge_y)
$ad_tree_view.Nodes.Add($(Add-ForestNodes $forest ([ref]$dc_hash))) | Out-Null
$ad_tree_view.Add_BeforeExpand({Add-ChildNodes $_})
$ad_tree_view.Add_AfterSelect({Get-NodeInfo $_ $dn_text_box})
$main_dlg_box.Controls.Add($ad_tree_view)
# /tree selector
if ($main_dlg_box.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK)
{
return $dn_text_box.Text
}
return $null
}
This is definition of the button that shall launch the browser:
$Select_AD_path = New-Object System.Windows.Forms.Button
$Select_AD_path.Text = "Browse..."
$Select_AD_path.Width = 100
$Select_AD_path.Height = 30
$Select_AD_path.Location = New-Object System.Drawing.Point(90,155)
$Select_AD_path.Font = 'Microsoft Sans Serif,10'
$Select_AD_path.add_Click({
$dn = Browse-AD
if ($dn)
{
$Location_val.Text = $dn
}
})
Also, I put the function to the value of a textbox, so that the browser launches before the script itself runs and prefills the AD path directly to the value I need it:
$Location_val = New-Object system.Windows.Forms.TextBox
$Location_val.multiline = $false
$Location_val.text = Browse-AD
$Location_val.width = 250
$Location_val.height = 20
$Location_val.location = New-Object System.Drawing.Point(200,160)
The precise error message is this:
Browse-AD : The term 'Browse-AD' 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 C:\Users\a.Petr.Synek\Documents\New_ADuser_woodgroup_complete.ps1:204 char:42
+ $Location_standard_val.Text = Browse-AD
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Browse-AD:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
At the 204th row there is this text: $Location_val.text = Browse-AD
As requested, my comment as answer:
In your script, you need to put the Browse-AD function on top and all the rest of your code beneath that.
If this order is incorrect, the first time running, the function is called before it has been parsed, giving you the error message.
The second time, PowerShell already parsed the entire code, so then the function is known. PowerShell (unlike VBScript) parses code from top to bottom.
I will need to go through many mailboxes and remove 'copy:' from the subject line of lots of meetings. At the moment the code works fine except that after the code performs the conflictresoltuionmode, alwaysoverwrite and I can see the successful result it does not save the update.
I have tried using the save function but its not working
#Variables and constants
$startdate = Get-Date
$enddate = $startdate.AddDays(365)
#$string = 'check'
#create a remote session to exchange
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchangeserver.com/PowerShell/ -Authentication Kerberos
Import-PSSession $Session -DisableNameChecking:$disablenamechecking
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
[Void] [Reflection.Assembly]::LoadFile($dllPath)
$MailboxName = "firstname.lastname#company.com"
$ExchVer = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
$exchService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchVer)
$exchservice.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
$exchService.UseDefaultCredentials = $true
$exchService.AutodiscoverUrl($MailboxName)
$Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchservice,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar)
$CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,1000)
$FindItems = $calendar.FindAppointments($CalendarView)
if($FindItems.Items.Count -gt 0)
{
foreach($Item in $finditems){
if ($item.Subject -like "check*") {
$item.subject.substring(6)
**$item.update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverWrite)
# the overwrite is successful but it's not saving**
#$item.Subject
}
#$ItemColl.Add($Item)
}
}
$item.Subject
Your code doesn't appear to actually make any change eg
$item.subject.substring(6)
Would simply print the first 6 character of the Subject if you wanted to change the subject you would need to have
$item.subject = "blah blah etc"
You don't have to call save as its only valid if the object is new all that is need is Update but it will only do anything if there is a property that has been changed which there isn't in the above example.
I have a function that retrieves a subnet from an Excel sheet (e.g. 10.123.123.64/26). I then trim the ".64/26" characters from the end and return it. When I recall the variable outside the function it only shows the first two characters (10)?
function GetSubnet() {
$FilePath = "C:\fwchange\IP.xlsx"
$SheetName = "STORE SUBNET MASK"
$Excel = New-Object -ComObject Excel.Application
$WorkBook = $Excel.Workbooks.Open($FilePath)
$WorkSheet = $WorkBook.Sheets.Item($SheetName)
$Range = $Worksheet.Range("B1").EntireColumn
$Search = $Range.Find($storeno)
Write-Host $search.Offset(0, 3).Text
$Subnet = $search.Offset(0, 3).Text
$Subnet1 = $Subnet.TrimEnd('64/26')
$WorkBook.Save()
$WorkBook.Close()
$Excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
Remove-Variable excel
Stop-Process -Name "Excel" -Force
return $Subnet1
}
I would like to be able to recall the variable $Subnet1 outside of the function.
#MathiasR.Jessen in comments section:
you need to assign the output from the function to a new variable in the calling scope: $Subnet1Result = GetSubnet