Powershell to set TransactionIsolation level of COM Plus components - powershell

How can i set the TRANSACTION ISOLATION LEVEL OF COM PLUS components to Any through powershell script.
I am trying with following code
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$apps = $comAdmin.GetCollection(“Applications”)
$apps.Populate();
foreach($app in $apps)
{
Write-Host $app.Name
if($app.Name -eq $ApplicationName)
{
$components = $apps.GetCollection("Components",$app.key)
$components.Populate()
foreach ($component in $components)
{
$componentName = $component.Name;
Write-Host "*"$componentName;
if($componentName -eq "WDA_DUP.Generic13")
{
$component.Value("TXIsolationLevel")=COMAdminTxIsolationLevelAny;
}
}
}
}
But not getting the purpose solved.Please Help me :)
`

Working script:
$ApplicationID = "{C0D4E2A4-CAC1-47BA-819C-EAB73E978FDF}"
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$apps = $comAdmin.GetCollection(“Applications”)
$apps.Populate();
foreach($app in $apps)
{
#Write-Host $app.Name
#Write-Host $app.Key
if($app.Key -eq $ApplicationID)
{
Write-Host $app.Name
$components = $apps.GetCollection("Components",$app.key)
$components.Populate()
foreach ($component in $components)
{
$componentName = $component.Name;
Write-Host "Set "$componentName;
$component.Value("TxIsolationLevel")=2
}
$components.SaveChanges()
}
}

Related

Parameterize a debug variable and insert it into the rest of the functions

$isDebug currently exists as a variable in the CleanStaleDevices function,
I need to make the variable into a optional parameter with a default value of $false.
Add the same parameter to the remaining functions.
I would like to set $isDebug as a variable at the initial function call, where CleanStaleDevices is called, then you can pass the value you set down the chain to the other functions. However, if you want to isolate debugging to an individual function you can override.
I tried converting $idDebug to a function itself but it didn't behave the way I was expecting
`function CleanStaleDevices($numDays) {
##Set debug flag
$isDebug = $true
#######Begin
Connect-AzureAD
###Get-AzureADDevice to get list of devices stale by 3 months and make sure devices aren't autopilot managed###
$dt = (Get-Date).AddDays($numDays)
$devices = Get-AzureADDevice -All:$true | Where-Object { $_.ApproximateLastLogonTimeStamp -le $dt } | select-object -Property AccountEnabled, DeviceId, DeviceOSType, DeviceOSVersion, DisplayName, DeviceTrustType, IsManaged, ApproximateLastLogonTimestamp
$fileNameDate = Get-Date -format "yyyyddMM"
$fileNameMiddle = "_AAD_Stale_Devices-"
##Get Intune devices
$intuneDevicesFileName = "$($fileNameDate)$($fileNameMiddle)Intune.csv"
$devices | ? { $_.IsManaged -eq $true } | Export-Csv c:\temp\$intuneDevicesFileName -NoTypeInformation
#######OUTSIDE ACTION#######
##Use Invoke-Device script to retire devices from generated CSV
##https://www.niallbrady.com/2017/08/23/getting-started-with-microsoft-graph-and-using-powershell-to-automate-things-in-intune/
#######END##################
$confirmation = Read-Host "Have you retired the detected Intune devices (y/n)?"
if ($confirmation -eq 'y') {
$hybridDevicesFileName = "$($fileNameDate)$($fileNameMiddle)Hybrid.csv"
$devices | ? { $_.DeviceTrustType -eq "ServerAd" } | Export-Csv c:\temp\$hybridDevicesFileName -NoTypeInformation
#######OUTSIDE ACTION#######
##Use DisableADComputersFromCSV.ps1 to disable the devices generated in the hybrid device csv
#######END##################
$confirmation = Read-Host "Have you disabled the on prem devices and ran a directory sync (y/n)?"
if ($confirmation -eq 'y') {
# proceed
###We don't have to open a new connection for each loop of the devices
$Connection = New-Object System.Data.SQLClient.SQLConnection
$serverName = "XXXXXXX"
$databaseName = "XXXXXXX"
$Connection.ConnectionString = "server='$serverName';database='$databaseName';trusted_connection=true;"
$Connection.Open()
if ($isDebug -eq $true) {
##debug array
$devicesweredisabled = #()
}
##Sort on DeviceTrustType so that AD Joined devices are disabled before AD registered
$devices = $devices | Sort-Object DeviceTrustType
foreach ($device in $devices) {
#if device is enabled
if ($device.AccountEnabled -eq $true) {
if ($isDebug -eq $true) {
##write to debug array
$devicesweredisabled += $device
Write-Host "Disable device" $device.DeviceId $device.DisplayName $device.AccountEnabled
}
else {
##don't disable Hybrid devices since they were disabled earlier
if ($_.DeviceTrustType -ne "ServerAd")
{
Write-Host "DISABLE " $device.DisplayName "with trust type" $device.DeviceTrustType
#$device.AccountEnabled = $false
}
##Check to see if device is in table already, if so check how long its been there
$disabledDateTimeValue = CheckIfDeviceISInTable $device.DeviceId $Connection
if ($null -eq $disabledDateTimeValue) {
##Device hasn't been added to table
WriteDisabledAADDevice $device.DeviceId $device.DisplayName $isDebug $Connection
}
}
}
else {
#device is not enabled
##Check to see if device is in table already, if so check how long its been there
$disabledDateTimeValue = CheckIfDeviceISInTable $device.DeviceId $Connection
if ($null -eq $disabledDateTimeValue) {
##Device is already disabled so we need to add it to the table for time tracking
WriteDisabledAADDevice $device.DeviceId $device.DisplayName $isDebug $Connection
}
else {
$numDaysSince = (Get-Date) - [datetime]$disabledDateTimeValue | % days
if ($numDaysSince -ge 90) {
if ($isDebug -eq $true) {
Write-Host "DEVICE WAS DELETED" $device.DeviceId $device.DisplayName $device.AccountEnabled
}
else {
Write-Host "DELETED..."
#device has been in table for 90 days so delete
##delete device
}
}
}
}
}
$Connection.Close()
if ($isDebug -eq $true) {
$devicesweredisabled | export-csv c:\temp\devicelist-olderthan-x-days-disabledtest.csv -NoTypeInformation
}
}
else{
Exit
}
}
else{
Exit
}
}
function WriteDisabledAADDevice {
Param(
[parameter(position = 3)]
$conn,
[parameter(position = 2)]
$logOnly,
[parameter(position = 1)]
$displayName,
[parameter(position = 0)]
$deviceId
)
$newId = (New-Guid).Guid
$disableDateTime = (Get-Date)
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $conn
$tableName = "DisabledAADDevice"
$insertquery = "
INSERT INTO $tableName
([DisabledAADDeviceId],[AADDeviceId],[DiplayName],[DisabledDateTime])
VALUES
('$newId','$deviceId','$displayName','$disableDateTime')"
if ($logOnly -eq $true) {
Write-Host $insertquery
}
else {
$Command.CommandText = $insertquery
$Command.ExecuteNonQuery()
}
}
function CheckIfDeviceISInTable {
Param(
[parameter(position = 1)]
$conn,
[parameter(position = 0)]
$deviceId
)
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $conn
$tableName = "DisabledAADDevice"
$selectQuery = "
Select [DisabledDateTime] FROM $tableName
WHERE [AADDeviceId] = '$deviceId'"
$Command.CommandText = $selectQuery
$resultValue = $Command.ExecuteScalar()
return $resultValue
}
CleanStaleDevices(-365)`

How to download a webstring from multiple web-servers in parallel via Powershell?

I need to download some webcontent from many servers in parallel as part of a scheduled job, but I cannot find a correct way to run the download in parallel/async. How can this be done?
Without any parallelism I can do it this way, but it is very slow:
$web = [System.Net.WebClient]::new()
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# $srvList is a list of servers of viariable length
$allData = ""
foreach ($srv in $srvList) {
$url = "https:\\$srv\MyWebPage"
$data = $web.DownloadString($url)
$allData += $data
}
But how to do this in parallel via "$web.DownloadStringAsync"?
I found this snippet, but I dont see how to get the result of each call and how to concatenate it:
$job = Register-ObjectEvent -InputObject $web -EventName DownloadStringCompleted -Action {
Write-Host 'Download completed'
write-host $EventArgs.Result
}
$web.DownloadString($url)
Does someone know, how to get this solved in a short & smart way?
The best and fastest way is using runspaces:
Add-Type -AssemblyName System.Collections
$GH = [hashtable]::Synchronized(#{})
[System.Collections.Generic.List[PSObject]]$GH.results = [System.Collections.Generic.List[string]]::new()
[System.Collections.Generic.List[string]]$GH.servers = #('server1','server2');
[System.Collections.Generic.List[string]]$GH.functions = #('Download-Content');
[System.Collections.Generic.List[PSObject]]$jobs = #()
#-----------------------------------------------------------------
function Download-Content {
#-----------------------------------------------------------------
# a function which runs parallel
param(
[string]$server
)
$web = [System.Net.WebClient]::new()
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https:\\$server\MyWebPage"
$data = $web.DownloadString($url)
$GH.results.Add( $data )
}
#-----------------------------------------------------------------
function Create-InitialSessionState {
#-----------------------------------------------------------------
param(
[System.Collections.Generic.List[string]]$functionNameList
)
# Setting up an initial session state object
$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
foreach( $functionName in $functionNameList ) {
# Getting the function definition for the functions to add
$functionDefinition = Get-Content function:\$functionName
$functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $functionName, $functionDefinition
# And add it to the iss object
[void]$initialSessionState.Commands.Add($functionEntry)
}
return $initialSessionState
}
#-----------------------------------------------------------------
function Create-RunspacePool {
#-----------------------------------------------------------------
param(
[InitialSessionState]$initialSessionState
)
$runspacePool = [RunspaceFactory]::CreateRunspacePool(1, ([int]$env:NUMBER_OF_PROCESSORS + 1), $initialSessionState, $Host)
$runspacePool.ApartmentState = 'MTA'
$runspacePool.ThreadOptions = "ReuseThread"
[void]$runspacePool.Open()
return $runspacePool
}
#-----------------------------------------------------------------
function Release-Runspaces {
#-----------------------------------------------------------------
$runspaces = Get-Runspace | Where { $_.Id -gt 1 }
foreach( $runspace in $runspaces ) {
try{
[void]$runspace.Close()
[void]$runspace.Dispose()
}
catch {
}
}
}
$initialSessionState = Create-InitialSessionState -functionNameList $GH.functions
$runspacePool = Create-RunspacePool -initialSessionState $initialSessionState
foreach ($server in $GH.servers)
{
Write-Host $server
$job = [System.Management.Automation.PowerShell]::Create($initialSessionState)
$job.RunspacePool = $runspacePool
$scriptBlock = { param ( [hashtable]$GH, [string]$server ); Download-Content -server $server }
[void]$job.AddScript( $scriptBlock ).AddArgument( $GH ).AddArgument( $server )
$jobs += New-Object PSObject -Property #{
RunNum = $jobCounter++
JobObj = $job
Result = $job.BeginInvoke() }
do {
Sleep -Seconds 1
} while( $runspacePool.GetAvailableRunspaces() -lt 1 )
}
Do {
Sleep -Seconds 1
} While( $jobs.Result.IsCompleted -contains $false)
$GH.results
Release-Runspaces | Out-Null
[void]$runspacePool.Close()
[void]$runspacePool.Dispose()
Finally I found a simple solution via events. Here is my code-snippet:
cls
Remove-Variable * -ea 0
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$srvList = #('srv1','srv2','srv3')
$webObjList = [System.Collections.ArrayList]::new()
$eventList = [System.Collections.ArrayList]::new()
$resultList = [System.Collections.ArrayList]::new()
$i=0
foreach ($srv in $srvList) {
$null = $webObjList.add([System.Net.WebClient]::new())
$null = $eventList.add($(Register-ObjectEvent -InputObject $webObjList[$i] -EventName DownloadStringCompleted -SourceIdentifier $srv))
$null = $resultList.add($webObjList[$i].DownloadStringTaskAsync("https://$srv/MyWebPage"))
$i++
}
do {sleep -Milliseconds 10} until ($resultList.IsCompleted -notcontains $false)
foreach ($srv in $srvList) {Unregister-Event $srv}
# show all Results:
$resultList.result

Query and exclude softwares installed on remote computers

I'm using the following powershell function to list the software installed on remote computers and export the data into various formats such as CSV, GridView or console :
Function Get-InstalledApplication
{
Param(
[Parameter(Mandatory=$true)]
[string[]]$Computername,
[String[]]$OutputType,
[string[]]$outpath
)
#Registry Hives
$Object =#()
$excludeArray = ("Security Update for Windows",
"Update for Windows",
"Update for Microsoft .NET",
"Security Update for Microsoft",
"Hotfix for Windows",
"Hotfix for Microsoft .NET Framework",
"Hotfix for Microsoft Visual Studio 2007 Tools",
"Microsoft Visual C++ 2010",
"cwbin64a",
"Hotfix")
[long]$HIVE_HKROOT = 2147483648
[long]$HIVE_HKCU = 2147483649
[long]$HIVE_HKLM = 2147483650
[long]$HIVE_HKU = 2147483651
[long]$HIVE_HKCC = 2147483653
[long]$HIVE_HKDD = 2147483654
Foreach($EachServer in $Computername){
$Query = Get-WmiObject -ComputerName $Computername -query "Select AddressWidth, DataWidth,Architecture from Win32_Processor"
foreach ($i in $Query)
{
If($i.AddressWidth -eq 64){
$OSArch='64-bit'
}
Else{
$OSArch='32-bit'
}
}
Switch ($OSArch)
{
"64-bit"{
$RegProv = GWMI -Namespace "root\Default" -list -computername $EachServer| where{$_.Name -eq "StdRegProv"}
$Hive = $HIVE_HKLM
$RegKey_64BitApps_64BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
$RegKey_32BitApps_64BitOS = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
$RegKey_32BitApps_32BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
#############################################################################
# Get SubKey names
$SubKeys = $RegProv.EnumKey($HIVE, $RegKey_64BitApps_64BitOS)
# Make Sure No Error when Reading Registry
if ($SubKeys.ReturnValue -eq 0)
{ # Loop through all returned subkeys
ForEach ($Name in $SubKeys.sNames)
{
$SubKey = "$RegKey_64BitApps_64BitOS\$Name"
$ValueName = "DisplayName"
$ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
$AppName = $ValuesReturned.sValue
$Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue
$Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue
$donotwrite = $false
if($AppName.length -gt "0"){
Foreach($exclude in $excludeArray)
{
if($AppName.StartsWith($exclude) -eq $TRUE)
{
$donotwrite = $true
break
}
}
if ($donotwrite -eq $false)
{
$Object += New-Object PSObject -Property #{
Application = $AppName;
Architecture = "64-BIT";
ServerName = $EachServer;
Version = $Version;
Publisher= $Publisher;
}
}
}
}}
#############################################################################
$SubKeys = $RegProv.EnumKey($HIVE, $RegKey_32BitApps_64BitOS)
# Make Sure No Error when Reading Registry
if ($SubKeys.ReturnValue -eq 0)
{
# Loop Through All Returned SubKEys
ForEach ($Name in $SubKeys.sNames)
{
$SubKey = "$RegKey_32BitApps_64BitOS\$Name"
$ValueName = "DisplayName"
$ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
$AppName = $ValuesReturned.sValue
$Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue
$Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue
$donotwrite = $false
if($AppName.length -gt "0"){
Foreach($exclude in $excludeArray)
{
if($AppName.StartsWith($exclude) -eq $TRUE)
{
$donotwrite = $true
break
}
}
if ($donotwrite -eq $false)
{
$Object += New-Object PSObject -Property #{
Application = $AppName;
Architecture = "32-BIT";
ServerName = $EachServer;
Version = $Version;
Publisher= $Publisher;
}
}
}
}
}
} #End of 64 Bit
######################################################################################
###########################################################################################
"32-bit"{
$RegProv = GWMI -Namespace "root\Default" -list -computername $EachServer| where{$_.Name -eq "StdRegProv"}
$Hive = $HIVE_HKLM
$RegKey_32BitApps_32BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
#############################################################################
# Get SubKey names
$SubKeys = $RegProv.EnumKey($HIVE, $RegKey_32BitApps_32BitOS)
# Make Sure No Error when Reading Registry
if ($SubKeys.ReturnValue -eq 0)
{ # Loop Through All Returned SubKEys
ForEach ($Name in $SubKeys.sNames)
{
$SubKey = "$RegKey_32BitApps_32BitOS\$Name"
$ValueName = "DisplayName"
$ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
$AppName = $ValuesReturned.sValue
$Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue
$Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue
if($AppName.length -gt "0"){
$Object += New-Object PSObject -Property #{
Application = $AppName;
Architecture = "32-BIT";
ServerName = $EachServer;
Version = $Version;
Publisher= $Publisher;
}
}
}}
}#End of 32 bit
} # End of Switch
}
#$AppsReport
$column1 = #{expression="ServerName"; width=15; label="Name"; alignment="left"}
$column2 = #{expression="Architecture"; width=10; label="32/64 Bit"; alignment="left"}
$column3 = #{expression="Application"; width=80; label="Application"; alignment="left"}
$column4 = #{expression="Version"; width=15; label="Version"; alignment="left"}
$column5 = #{expression="Publisher"; width=30; label="Publisher"; alignment="left"}
if ($outputType -eq "Console")
{
"#"*80
"Installed Software Application Report"
"Number of Installed Application count : $($object.count)"
"Generated $(get-date)"
"Generated from $(gc env:computername)"
"#"*80
$object |Format-Table $column1, $column2, $column3 ,$column4, $column5
}
elseif ($OutputType -eq "GridView")
{
$object|Out-GridView
}
elseif ($OutputType -eq "CSV")
{
[string]$FileDS = Get-Date -Format "yyyyMMdd"
[string]$outFile = $outpath+'\'+$computername+'_'+$FileDS+'.csv'
New-Item -ItemType file $outfile -Force
$object | export-csv -path $outfile
}
else
{
write-host " Invalid Output Type $OutputType"
}
}
I'm also using the code to exclude some application from a list. I have a problem on PCs running a 32-bit version of Windows (tested on a 32-bit Windows 7) : applications excluded from this list still appear in the output. No problem on 64-bit systems however.
Ideas of what's wrong ?
Thanks

DataGridView. Run Job while entering new row parallel

The script included is to check the replication and repair for each Server that I add. The goal I have in mind is for it to automatically check the connection of each computer as I add them as well as check the uptime.
The current issue I'm having is that it will delay to check the uptime before it allows me to input my next computer.
As you can see in my script I'm trying to use a start-job which is not working at all for me as it says the 'ComputerName' is null, but the ComputerName is set in the Get-Uptime function.
I may be going about this all wrong. Any help would be great!!
function Check-Replication {
#----------------------------------------------
#region Import the Assemblies
#----------------------------------------------
[void][Reflection.Assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Reflection.Assembly]::Load('System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Reflection.Assembly]::Load('System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
#endregion Import Assemblies
$base64Image = "iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAABGdBTUEAALGPC/xhBQAAAAJiS0dEAP+Hj8y/AAAACXBIWXMAAWG3AAFhtwFW7IyrAAAAB3RJTUUH4goDDxY48JvtEgAAAg9JREFUKM9NkT9MU1EUxn/33kf/APVPYQGaYImLYQAikU6kidFoWBwYjLgw6SZxkLhgnExc0A1ZHDC6uOmMDQ5KLCYuqINxoFgq2Ce0fbx/912GvhDOlzN9X77znXMEAFyhL7Uxmbl9vjjQn1ahrv35Vdp7NbxWc1eJaxFJIX9h+UZ9yZTMF/PVlM1Hs2Jm6yPLl/KwCIinPGZwxHsxPnGTXhQSgSEi4oB3rK7LO1vfFlA75Ib2X54rTJNFIBGAISLE0MdOrjo69GHDlteT9nxXYZQMEWBOQNPBGJmCPX81qZzL/kIuPUwPHVjxSIiI0Pj4/MXOV8pWa6Yzm0XFhIzXimLAGTqzrRkrKnbThSYgxELEwoiQkJCATrppFi09kCKJwSNJgEEgMBhCAjwCEqTQA5ZW7SME+AiiE24BPgaJQiuptI5zaCLMcRs0bSZEaSm3D/HwCdBodCzS6Dibh4valrLUoEGLQ1x8guPoPh6HODRpQkkNOs5UIp0mgUIAEZoQH5cm+/yjym6965GarXwfdC8msOJfhrFPW1Sjgl65tqRsfXrz/4SXkxg0IR4uDg322aPGFo3PPfc399QD3ti95dZYKxfg4+LQ4gCbXapUaKwn7/78MYeA59yjkK8/NNPpsxlSKDQuTRxbvs0++fT7GXOI9g+n6E+VJw9umaLJhcrSoiJKp16Pr1Xd9wAcAYNiEWcBi781AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTEwLTAzVDE1OjIyOjU2LTA0OjAwISeC9gAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0xMC0wM1QxNToyMjo1Ni0wNDowMFB6OkoAAAAASUVORK5CYII="
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageGrey = [System.Drawing.Bitmap]::FromStream($memStream, $true)
$base64Image = "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH4goDDxstKOh3tAAABJVJREFUOMtVlNtvVFUUxn/r3M8w7bSddloYWkpALlqoEBJ9IIQoSUUTEYj6B8CLMSbySOKTvtQYnlDf1ITggwHFiEAIl4CVxPBAAhQKIVwCpXTaTjuXM3PmXOZsH6aA7uTbe2Vl5Vt7rXxrCf85V69epVKpkMvlejVNW2saZtq2HU3XdA+gmcRdYRRKGIalJEkm6vX6M8uy1ObNm19wyHPj2rVrJEliua671bGdnFetPbwwdm7g1v3xVTPFmXbTMLUlqXRheM3wo5HtI0U3neoJgqAahuGYpmn+8PDwS8Lx8XGSJGlzHPtz07SWnT5/ev63yye2VbTqJiujp6wlpogIoR+rZjXxcnbvnd1bd13Z/uZ2I4zDsu/7h3RdXxgaGkKuX79Oo9EwM5n2L0zD+uT4mWP1Hy791FfL1my1VBGkAiIjBAEjNnHqDvqMTrbWGe/fvr/47rb39DAKf/Y876Bpmr5hGAau6+7WNf3T38+e0L85e2h5qb+kq/6EZrYJ7SB2qzMqBKoK3dF5NjlljJ79utc0zOCtN97eZ9nWDdd1fzR83+9LuakDE/fuZL87972aWzYrskpQeZBuDdIKLEAJEivwhKRdoeyEyeYk354/bK/Mr7SX9/Z/Vi6VL2oi8m4QhJuOXfiVh9YjkRUtMpYCvQp6gRyQU5AD1QcsVUgeZFC4pSb4458/iaJoSET2akqpXZNTj+0rD/9G9SXQI0g3SBeoTlDtQBuojEAGJAN0AVmgB5KehL8eXGa2OGskSfK+EUfx6/cfP6DQfIZ0AG0K0kAaJAU4gC6AAmNRY3ErCW2tJE8LT5mcfUrKTW3U6vV6R6FYIDBDcARsWj0zQAxpkT2HAZiAqVAmYCtwFL40KJaL+HU/ozUaDYmiCEFQAiIvJ0ct3uqF9XIe5LlDtcQcxTG+74vWTJrltJPGbtrQWJRG1CpLxQrVBEkUkihoKogXEQEhSAAOLq7h0Gw2K5pK1I2u9i5yeg7KIFXAE1Qd8IEGECyiAcoHaoKqAR6oMuTtPGkrTaKSW5ph6KeWpNqjDd0b0GcENStQBJkHKYFUgEVIGaQksNCKUXOgF3U29W1GFz0xDOOUls12n7Rt8+aWFVsYjAZRTxLUlIJpoADMPoe03gIwrWAKeKxYr69nY+8QmsjdTCZzXM/n85XBFSuCZpS80yEdxuPJJ9TCKpIIhK2yVX3xp0VgRmAK5KGivzTAx2s+JJvqjjq7Or86evToGX10dJSBgYG7Cwvz3SbmlqVmn3hzVYJKiBEYaDUdKYFWFIw5E6dg4046rA3W8MGqPfSlelVHR8eRda+uGx3eOBwKwKVLl2hra+u6ffv2l4Xpwr6F6rxzv/SAp/EkDScAp6UPLdBwohT97gCr21eRttJRNps9svqV1Qc9z5vduXPnywU7NjZGJpNxb9y8+dH83NyBeq021IgC3U8CYmJEwBILx3AxdbPpOs69bHf28Lq1646Uy2Vvx44d/9/YAIVCgVwux4WLFwann03v9TxvTxAEr8VxnBEEXdcrlmVNpNvSJ3t6en4ZGRm5PzU1pfL5/AuOfwFWfAyFldyKLAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0xMC0wM1QxNToyNzo0NS0wNDowMDpMU7EAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMTAtMDNUMTU6Mjc6NDUtMDQ6MDBLEesNAAAAAElFTkSuQmCC"
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageGreen = [System.Drawing.Bitmap]::FromStream($memStream, $true)
$base64Image = "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"
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageRed = [System.Drawing.Bitmap]::FromStream($memStream, $true)
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$labelTypeEachComputerName = New-Object 'System.Windows.Forms.Label'
$textbox1 = New-Object 'System.Windows.Forms.TextBox'
$datagridview1 = New-Object 'System.Windows.Forms.DataGridView'
$buttonRun = New-Object 'System.Windows.Forms.Button'
$Online = New-Object 'System.Windows.Forms.DataGridViewImageColumn'
$Uptime = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$Computer = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$Status = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#----------------------------------------------
# Function Get-Uptime
#----------------------------------------------
#region - Get-Uptime
$Uptime1 = {
function Get-Uptime {
Params ($ComputerName)
$global:ComputerName = $row.cells[2].Value
$os = Get-WmiObject win32_operatingsystem -ComputerName $ComputerName -ErrorAction SilentlyContinue
if ($os.LastBootUpTime) {
$uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime)
#Write-Output ("Last boot: " + $os.ConvertToDateTime($os.LastBootUpTime) )
Write-Output ("" + $uptime.Days + "d " + $uptime.Hours + "h " + $uptime.Minutes + "m" )
} else {
Write-Warning "Unable to connect to $computername"
}
}
}
#endregion
#----------------------------------------------
# User Generated Script
#----------------------------------------------
$FormEvent_Load = {
}
$textbox1_Validated = {
if ($textbox1.Text -ne "") {
$i = $datagridview1.Rows.Add(1)
$row = $datagridview1.Rows[$i]
$row.SetValues(#($imageGrey,'',$textbox1.Text,'pending'))
$textbox1.Text = ''
$textbox1.Focus()
if ($row.Cells[2].Value -ne "") {
if (Test-Connection -ComputerName $row.cells[2].Value -Count 1 -Quiet) {
$Time = Get-Date
Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime -ComputerName $args[0])} -Args $row.cells[2].Value |
#Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime)}|
Wait-Job | Receive-Job
$row.SetValues(#($imageGrey,($Uptime),$row.Cells[2].Value))
#Remove-Job -Name CheckSiteUptime
$Time = Get-date
$row.Cells[0].Value = $imageGreen
} else {
$row.Cells[0].Value = $imageRed}
}
}
}
$buttonRun_Click = {
$datagridview1.Rows | ForEach-Object {
$row = [System.Windows.Forms.DataGridViewRow]$_
$CommandResult = Invoke-Command -ComputerName $row.cells[2].Value -ArgumentList $row -ScriptBlock{
Param($row)
Import-Module Hyper-V
if ((Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Get-VMReplication -ErrorAction Stop).Replicationhealth -eq 'critical') {
try{
Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Resume-VMReplication -ErrorAction Stop
if ((Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Get-VMReplication -ErrorAction Stop).Replicationhealth -eq 'critical') {
throw [System.Exception] "Replicationhealth critical"
}
} catch {
try{
Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Resume-VMReplication -Resynchronize -ErrorAction Stop
} catch {
return 'FAILED: Resume-VMReplication -Resynchronize'
break
}
return 'Successful: Resume-VMReplication -Resynchronize'
break
}
return 'Successful: Resume-VMReplication'
} else {
return 'Successful: No action replication is NOT critical'
}
}
switch ($CommandResult) {
"FAILED: Resume-VMReplication -Resynchronize" {
$row.Cells | %{$_.Style.BackColor = 'pink'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: Resume-VMReplication -Resynchronize" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: Resume-VMReplication" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: No action replication is NOT critical" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
}
}
$datagridview1.ReadOnly = $true
}
# --End User Generated Script--
#----------------------------------------------
#region Generated Events
#----------------------------------------------
$Form_StateCorrection_Load = {
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed = {
#Remove all event handlers from the controls
try {
$textbox1.remove_Validated($textbox1_Validated)
$buttonRun.remove_Click($buttonRun_Click)
$form1.remove_Load($FormEvent_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
} catch {
Out-Null <# Prevent PSScriptAnalyzer warning #>
}
}
#endregion Generated Events
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
$form1.SuspendLayout()
#
# form1
#
$form1.Controls.Add($labelTypeEachComputerName)
$form1.Controls.Add($textbox1)
$form1.Controls.Add($datagridview1)
$form1.Controls.Add($buttonRun)
$form1.AutoScaleDimensions = '6, 13'
$form1.AutoScaleMode = 'Font'
$form1.ClientSize = '625, 600'
$form1.FormBorderStyle = 'FixedDialog'
$form1.MaximizeBox = $False
$form1.MinimizeBox = $False
$form1.Name = 'form1'
$form1.StartPosition = 'CenterScreen'
$form1.Text = 'Replication Check'
$form1.add_Load($FormEvent_Load)
#
# labelTypeEachComputerName
#
$labelTypeEachComputerName.Location = '20, 18'
$labelTypeEachComputerName.Name = 'labelTypeEachComputerName'
$labelTypeEachComputerName.Size = '240, 49'
#$labelTypeEachComputerName.TabIndex = 5
$labelTypeEachComputerName.Text = 'Type each computer name ending with a <tab> it will be added to the list. Click run when alll have been added.'
$labelTypeEachComputerName.UseCompatibleTextRendering = $True
#
# textbox1
#
$textbox1.CharacterCasing = 'Upper'
$textbox1.Location = '20, 81'
$textbox1.Name = 'textbox1'
$textbox1.Size = '285, 20'
#$textbox1.TabIndex = 1
$textbox1.add_Validated($textbox1_Validated)
#
# datagridview1
#
$datagridview1.AllowUserToAddRows = $False
$datagridview1.AllowUserToDeleteRows = $False
$datagridview1.AllowUserToResizeColumns = $True
$datagridview1.AllowUserToResizeRows = $False
$datagridview1.ColumnHeadersHeightSizeMode = 'AutoSize'
[void]$datagridview1.Columns.Add($Online)
[void]$datagridview1.Columns.Add($Uptime)
[void]$datagridview1.Columns.Add($Computer)
[void]$datagridview1.Columns.Add($Status)
$datagridview1.columns[0].Width = '40'
$datagridview1.columns[3].Width = '250'
$datagridview1.Location = '20, 113'
$datagridview1.Name = 'datagridview1'
$datagridview1.ReadOnly = $True
$datagridview1.Size = '583, 470'
$datagridview1.TabIndex = 3
$datagridview1.DefaultCellStyle.WrapMode = "True"
#
# buttonRun
#
$buttonRun.Location = '325, 80'
$buttonRun.Name = 'buttonRun'
$buttonRun.Size = '75, 23'
$buttonRun.TabIndex = 2
$buttonRun.TabStop = $False
$buttonRun.Text = 'Run'
$buttonRun.UseCompatibleTextRendering = $True
$buttonRun.UseVisualStyleBackColor = $True
$buttonRun.add_Click($buttonRun_Click)
#
# Online
#
$Online.HeaderText = 'Online'
$Online.Name = 'Online'
$Online.DataPropertyName = 'Online'
#
# Uptime
#
$Uptime.HeaderText = 'Uptime'
$Uptime.Name = 'Uptime'
$Uptime.ReadOnly = $True
#
# Computer
#
$Computer.HeaderText = 'Server'
$Computer.Name = 'Server'
$Computer.ReadOnly = $True
#
# Status
#
$Status.HeaderText = 'Status'
$Status.Name = 'Status'
$Status.ReadOnly = $True
$form1.ResumeLayout()
#endregion Generated Form Code
#----------------------------------------------
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call the form
Check-Replication | Out-Null
Because PowerShell jobs run in a separate runspace, even declaring a variable as $global: does not make it available inside your job. Instead, you need to pass the value in to your job when you create it.
For example, you could change your code as follows:
...
Function Get-Uptime {
params ($ComputerName)
$global:ComputerName = $ComputerName
...
Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime -ComputerName $args[0])} -Args $row.cells[2].Value
A similar issue is described here: https://social.technet.microsoft.com/Forums/ie/en-US/5b369c15-d2ad-4ee8-a1fc-3f0ca8df230a/powershell-jobs-and-global-variables?forum=ITCG
Another resource on some options other than PS jobs, which tend to be relatively inefficient: https://randombrainworks.com/2018/01/28/powershell-background-jobs-runspace-jobs-thread-jobs/
Another way around your base issue of de-coupling your form/GUI from your backend code is to use runspaces and a synchronized hashtable. The advantage of this model is that your can have many threads simultaneously performing work and actively updating your form, and instead of passing variables around, you have a single copy and pass references.
This is a great article to get started: https://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/

PowerShell: Variable loses its value in userform

I have a script with a userform with which you can edit an ad user object.
The script runs fine directly on our server but when I try to run it from my system with admin privileges, New-PSSession and a few Invoke-Command's the necessary variables are losing their values.
Here's my code (Some stuff has been censored):
#--------------------#
# Function GUI > GUI #
#--------------------#
Function GUI
{
#---Param
[String]$BadgeListCSV = "link" # -> Badge list
[Bool]$UserChk = $False # -> Indicates if the user has been found
[Bool]$BadgeChk = $False # -> Indicates if the badge is already linked with an ad object
[Int]$BadgeIndex = 1 # -> Badge Nr.
#Global variables
Set-Variable -Name Exit -Value $True -Scope Global
#---Importing badge list
Try
{
$BadgeList = Import-CSV $BadgeListCSV
}
Catch
{
DisplayMSGBox -MSGText "Could not access CSV file." -AddErrorInfo $True | Out-Null
LogFileCleanUp
[System.Environment]::Exit(0)
}
ShowWallBoard
#---Form
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(184,197)
$Form.Font = New-Object System.Drawing.Font("Segoe UI",9,0,3,1)
$Form.FormBorderStyle = "FixedSingle"
$Form.MaximizeBox = $False
$Form.Text = "S/R Visitor Badge"
$Form.StartPosition = "CenterScreen"
#---GroupBox Badges
$GBBadges = New-Object System.Windows.Forms.GroupBox
$GBBadges.Location = New-Object System.Drawing.Size(10,5)
$GBBadges.Size = New-Object System.Drawing.Size(158,70)
$GBBadges.Text = "Badge"
#Badge choice
$CBBadgeChoice = New-Object System.Windows.Forms.ComboBox
$CBBadgeChoice.Location = New-Object System.Drawing.Size(10,20)
$CBBadgeChoice.Size = New-Object System.Drawing.Size(110)
$CBBadgeChoice.FlatStyle = "PopUp"
$CBBadgeChoice.DropDownStyle = 2
#---Retrieving badge list
Try
{
ForEach($Badge in $BadgeList)
{
$CBBadgeChoice.Items.Add("Visitor Badge $BadgeIndex") | Out-Null
$BadgeIndex++
}
}
Catch
{
DisplayMSGBox -MSGText "Could generate badge choice combobox." -AddErrorInfo $True | Out-Null
LogFileCleanUp
[System.Environment]::Exit(0)
}
$CBBadgeChoice.SelectedIndex = 0
#Unlink
$ChBUnlink = New-Object System.Windows.Forms.CheckBox
$ChBUnlink.Location = New-Object System.Drawing.Size(10,47)
$ChBUnlink.Size = New-Object System.Drawing.Size(135,18)
$ChBUnlink.FlatStyle = "Flat"
$ChBUnlink.Text = "Unlink this badge"
#PictureBox Badge
$PBBadge = New-Object System.Windows.Forms.PictureBox
$PBBadge.Location = New-Object System.Drawing.Size(130,23)
$PBBadge.Size = New-Object System.Drawing.Size(16,16)
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
#---GroupBox User
$GBUser = New-Object System.Windows.Forms.GroupBox
$GBUser.Location = New-Object System.Drawing.Size(10,77)
$GBUser.Size = New-Object System.Drawing.Size(158,53)
$GBUser.Text = "User"
#UserName
$TBUserName = New-Object System.Windows.Forms.TextBox
$TBUserName.Location = New-Object System.Drawing.Size(10,20)
$TBUserName.Size = New-Object System.Drawing.Size(110)
$TBUserName.BorderStyle = 1
#PictureBox UserName
$PBUserName = New-Object System.Windows.Forms.PictureBox
$PBUserName.Location = New-Object System.Drawing.Size(130,23)
$PBUserName.Size = New-Object System.Drawing.Size(16,16)
$PBUserName.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
#---Buttons
$BValidate = New-Object System.Windows.Forms.Button
$BValidate.Location = New-Object System.Drawing.Size(10,139)
$BValidate.Size = New-Object System.Drawing.Size(75,23)
$BValidate.FlatStyle = "PopUp"
$BValidate.Text = "Validate"
$BConfirm = New-Object System.Windows.Forms.Button
$BConfirm.Location = New-Object System.Drawing.Size(93,139)
$BConfirm.Size = New-Object System.Drawing.Size(75,23)
$BConfirm.FlatStyle = "PopUp"
$BConfirm.Text = "Confirm"
$BConfirm.Enabled = $False
#---Eventhandling
$DisableTextBox=
{
#---"Unlink this badge" is unchecked
if($ChBUnlink.Checked -eq $False)
{
#---Enable texbox
$TBUserName.Enabled = $True
#---Clear textbox
$TBUserName.Text = ""
#---Set both picture boxes to cross.png
$PBBadge.Image = $PBUserName.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
}
#---"Unlink this badge" is checked
if($ChBUnlink.Checked -eq $True)
{
#---Disable textbox
$TBUserName.Enabled = $False
#---Clear textbox
$TBUserName.Text = ""
#---Set the picture box next to the username input textbox to tick.png
$PBUserName.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\tick.PNG")
#---Setting badge check
$BadgeChk = $False
#---Set the picture box next to badge choice combobox to tick.png
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
}
}
#---Buttons On-Click-Actions
$BValidate_OnClick=
{
#---Param
[String]$UserName = $TBUserName.Text # -> Username
[Int]$BadgeCSVID = $CBBadgeChoice.SelectedIndex # -> Index which indicates which badge got selected: Index = 0 -> Visitor Badge 1, Index 1 -> Visitor Badge 2
[Long]$BadgeID = $BadgeList[$BadgeCSVID].ID # -> Getting badge id from csv file
$Form.Enabled = $False
Try
{
#---UserChk
if($UserName -ne "")
{
$UserChk = Invoke-Command -Session $OurADServer -ScriptBlock{Param($UserName) [Bool](Get-ADUser -Filter { sAMAccountName -eq $UserName } -Searchbase "SB")} -ArgumentList $UserName
if($UserChk -eq $False)
{
$PBUserName.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
}
ElseIf($UserChk -eq $True)
{
$PBUserName.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\tick.PNG")
}
}
}
Catch
{
DisplayMSGBox -MSGText "Could not validate the user." -AddErrorInfo $True | Out-Null
LogFileCleanUp
[System.Environment]::Exit(0)
}
Try
{
#---BadgeChk
$BadgeChk = Invoke-Command -Session $OurADServer -ScriptBlock{Param($BadgeID) [Bool](Get-ADObject -Filter { Pager -eq $BadgeID })} -ArgumentList $BadgeID
if($BadgeChk -eq $True)
{
#---Retrieving all linked ad objects
$AllLinkedObjectsArray = New-Object System.Collections.ArrayList
$AllLinkedObjects = Invoke-Command -Session $OurADServer -ScriptBlock{Param($BadgeID) Get-ADObject -Filter { Pager -eq $BadgeID }} -ArgumentList $BadgeID
ForEach($Object in $AllLinkedObjects)
{
$AllLinkedObjectsArray.Add($Object.Name) | Out-Null
}
#---Joins array into string with breaks
$AllLinkedObjectsString = $AllLinkedObjectsArray -Join "
"
if($ChBUnlink.Checked -eq $False)
{
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
if((DisplayMSGBox -MSGText ($CBBadgeChoice.SelectedItem + " is already linked with the following objects:`n`n$AllLinkedObjectsString`n`nDo you wish to clear these links?”) -MSGButtons YesNo -MSGIcon Question) -eq "Yes")
{
ReleaseVisitorBadge $AllLinkedObjectsString $BadgeCSVID $BadgeID
}
}
elseif($ChBUnlink.Checked -eq $True)
{
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\tick.PNG")
}
}
elseif($BadgeChk -eq $False)
{
if($ChBUnlink.Checked -eq $False)
{
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\tick.PNG")
}
elseif($ChBUnlink.Checked -eq $True)
{
$PBBadge.Image = [System.Drawing.Image]::FromFile("$ScriptPath\images\cross.PNG")
DisplayMSGBox -MSGText ($CBBadgeChoice.SelectedItem + " is currently not in use.") -MSGIcon Information | Out-Null
}
}
}
Catch
{
DisplayMSGBox -MSGText "Could not validate the badge." -AddErrorInfo $True | Out-Null
LogFileCleanUp
[System.Environment]::Exit(0)
}
$Form.Enabled = $True
#---Enabling / disabling the button "Confirm"
if(($BadgeChk -eq $False -and $UserChk -eq $True) -or ($BadgeChk -eq $True -and $ChBUnlink.Checked -eq $True))
{
$BConfirm.Enabled = $True
}
else
{
$BConfirm.Enabled = $False
}
}
$BConfirm_OnClick=
{
if($BadgeChk -eq $False -and $UserChk -eq $True)
{
Set-Variable -Name Exit -Value $False -Scope Global
$Form.Close()
SetVisitorBadge $UserName $BadgeCSVID $BadgeID
}
ElseIf($BadgeChk -eq $True -and $ChBUnlink.Checked -eq $True)
{
Set-Variable -Name Exit -Value $False -Scope Global
$Form.Close()
ReleaseVisitorBadge $AllLinkedObjectsString $BadgeCSVID $BadgeID
}
}
#---Adding Elements to the form
$BValidate.Add_Click($BValidate_OnClick)
$BConfirm.Add_Click($BConfirm_OnClick)
$ChBUnlink.Add_CheckedChanged($DisableTextBox)
$Form.Add_Shown({$Form.Activate(); $TBUserName.Focus()})
$GBBadges.Controls.Add($CBBadgeChoice)
$GBBadges.Controls.Add($PBBadge)
$GBBadges.Controls.Add($ChBUnlink)
$GBUser.Controls.Add($TBUserName)
$GBUser.Controls.Add($PBUserName)
$Form.Controls.Add($GBBadges)
$Form.Controls.Add($GBUser)
$Form.Controls.Add($BValidate)
$Form.Controls.Add($BConfirm)
$Form.ShowDialog()| Out-Null
}
I have two options in my userform. After the user has entered the data, he has to validate it by clicking on "Validate". If everything is correct, the button "Confirm" gets activated and the AD user object may be changed.
However, after validating the data and then clicking on "Confirm" all necessary variables lost their values and I don't know why.
As you can see below, everything is set after validating the data but when I try to confirm it, all values are gone.
The script worked just fine as it is now when run directly on our AD server. All I did was trying to run it via my system by adding a remote session and Invoke-Command's. Could this really be an issue here?
Thanks for any help.