Copy Azure Storage Table Service data to SQL Server - sql-server

How can I copy huge amounts of data from Azure Storage Table Service to SQL Server using PowerShell?
AzTable which Microsoft recommends using does not support incremental load without underlying information about partition keys, and the documentation website is down...:
https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell

I am answering this question myself, because I have lots of trouble findind a solution online, and would like to help other people with this crap.
$StorageAccountResourceGroup = "MyResourceGroup"
$StorageAccountName = "MyStorageAccount"
$TableName = "MyStorageTableName"
$SqlConnectionString = "MySqlConnectionString"
$BulkCopy = [System.Data.SqlClient.SqlBulkCopy]::new()
$BulkCopy.DestinationTableName = "[myschema].[mytablename]"
$DataTable = <<Generate datatable from SQL-table>> # Code not included
Connect-AzAccount
$StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $StorageAccountResourceGroup -AccountName $StorageAccountName | Where-Object -FilterScript {$_.KeyName -eq "Key1"}).Value
$Context = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
$CloudTable = (Get-AzStorageTable -Context $Context -Name $TableName).CloudTable
$TableQuery = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Token = $null
BulkCounter = 0
do{
$ReturnObject = $CloudTable.ExecuteQuerySegmented($TableQuery, $Token)
$Token = $ReturnObject.ContinuationToken
foreach($Entry in $ReturnObject){
$Row = $DataTable.NewRow()
foreach($Column in $DataTable.Columns){
if($Column.ColumnName -eq "TimeStamp"){
$Value = $Entry.TimeStamp
} elseif($Column.ColumnName -eq "RowKey"){
$Value = $Entry.RowKey
} elseif($Column.ColumnName -eq "PartitionKey"){
$Value = $Entry.PartitionKey
} else {
if($Column.DataType -eq [System.Decimal]){
$Value = $Entry.Properties.$($Column.ColumnName).DoubleValue
} elseif($Column.DataType -eq [System.String]){
$Value = $Entry.Properties.$($Column.ColumnName).StringValue
} elseif($Column.DataType -eq [System.Guid]){
$Value = $Entry.Properties.$($Column.ColumnName).GuidValue
} elseif($Column.DataType -eq [System.datetimeoffset]){
$Value = $Entry.Properties.$($Column.ColumnName).DateTimeOffsetValue
} elseif($Column.DataType -eq [System.Int32]){
$Value = $Entry.Properties.$($Column.ColumnName).Int32Value
} elseif($Column.DataType -eq [System.Int64]){
$Value = $Entry.Properties.$($Column.ColumnName).Int64Value
} elseif($Column.DataType -eq [System.Boolean]){
$Value = $Entry.Properties.$($Column.ColumnName).BooleanValue
} elseif($Column.DataType -eq [System.Binary]){
$Value = $Entry.Properties.$($Column.ColumnName).BinaryValue
}
}
if([System.String]::IsNullOrWhiteSpace($Value)){
$Value = [System.DBNull]::value
}
$Row.($Column.ColumnName) = $Value
}
$DataTable.Rows.Add($Row)
$Counter++
}
$BulkCounter ++
if($BulkCounter % 25 -eq 0 -and $BulkCounter -ne 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
$BulkCounter = 0
}
} while ($Token)
if($Datatable.rows.count -gt 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
}
Here is also some functions for automatically generating tables from storage account tables:
function ConvertTo-SqlTypeFromEDM {
param (
$EDMType
)
if($EDMType -eq "String"){
return "varchar(100)"
} elseif($EDMType -eq "Guid"){
return "uniqueidentifier"
} elseif ($EDMType -eq "DateTime"){
return "datetimeoffset(0)"
} elseif ($EDMType -eq "Binary"){
return "varbinary(max)"
} elseif ($EDMType -eq "Int32"){
return "int"
} elseif ($EDMType -eq "Int64"){
return "long"
} elseif ($EDMType -eq "Double"){
return "decimal(25,5)"
} elseif ($EDMType -eq "Boolean"){
return "bit"
} else {
throw "Tybe $EDMType not implemented"
}
}
function Get-SqlQueryFromStorageTableSerivce {
param(
$CloudTable,
$SchemaName
)
$Query = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Query.TakeCount = 1
$Token = $null
$Result = $CloudTable.ExecuteQuerySegmented($Query, $Token)
$TableName = $CloudTable.Name
$TableString = "DROP TABLE IF EXISTS [$SchemaName].[$TableName]`n"
$TableString += "CREATE TABLE [$SchemaName].[$TableName] (`n`t"
$ColumnString = #()
$TableKeys = #()
if($Result.PartitionKey){
$ColumnString += "[PartitionKey] varchar(100) NOT NULL"
$TableKeys += "[PartitionKey]"
}
if($Result.RowKey){
$ColumnString += "[RowKey] varchar(100) NOT NULL"
$TableKeys += "[RowKey]"
}
if($Result.Timestamp){
$ColumnString += "[Timestamp] datetimeoffset(0) NULL"
}
foreach($Column in $Result.Properties.Keys){
$ColumnString += "[$Column] $(ConvertTo-SqlTypeFromEDM -EDMType $Result.Properties.$Column.PropertyType) NULL"
}
$TableString += $ColumnString -join ",`n`t"
$TableString += "`nCONSTRAINT [PK_1_$($TableName)_1] PRIMARY KEY CLUSTERED`n"
$TableString += "(`n`t" + ($TableKeys -join ",`n`t")
$TableString += "`n)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF, DATA_COMPRESSION = PAGE) ON [PRIMARY]"
$TableString += "`n) ON [PRIMARY]`n"
return $TableString
}

Related

Powershell , array1 , Array2 , find String, replace String

Well i want only to know what i Have to do if that what read out (includs like words like "leiter" in Verkaufsabteilungsleiter or Gesamtleitung and save in Variables like MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3 filtered out that this things doesn't generate.
Or It finds things like Verkaufsabteilung-Inland and add there something in String.
So i think to compare two arrays are shorter If i write line for line.
if ($Abt -match "leiter") {$Standortsleitunglesen2 = $Mtl2 + "s" + "leitung" + "-" + "Lesen"}
if ($Abt -match "leiter") {$Standortsleitunglesen2 = $Mtl2 + "s" + "leitung" + "-" + "Lesen"}
if ($Standortsleitunglesen2 -match "Geschäft" ) {$Standortsleitunglesen2 = "" }
So i can set the terms in array2 and i don't need to write lots of lines and type it manualy. I hope you understand it now.
So I think my Solution goes in following direction:
$array = #($MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "leitung"
for([int] $i = 0; $i -le ($array.Count -1); $i++)
{
foreach($word in $array2)
{
if($array[$i] -like "*$word*")
{
if ($array[$i] -match $MitgliedÄndern2) { ($MitgliedÄndern2 = "") }
if ($array[$i] -match $Mitgliedlesen2) { ($Mitgliedlesen2 = "") }
if ($array[$i] -match $MitgliedÄndern3) { ($MitgliedÄndern3 = "") }
if ($array[$i] -match $Mitgliedlesen3) { $Mitgliedlesen3 = ""}
$array[$i] = ""
}
}
}
I have a problem in Variables would generate Usernames of a Table of CSV.
CSV: Inhalt
Nummer;Ordner1;Ordner2;Ordner3;Benutzername;;;Beschreibung;Mitglied;Mitglied 2;Gruppenbeschreibung;Gruppenbeschreibung 2
1;Hamburg;Geschäftsleitung;HH-GL;Stefan Berti;;;Standortleiter;GG-H-Geschäftsleiter;;Geschäftsleitung Hamburg;
in array2 i would like to Words that the the loop have to search in array1.
and if he find the string of array2 for example 'leiter' or another word like "Sekretär" in $array1 in $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 it would be Write "" in $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3.
I have a method that works with an easy array but that method doesn't work in that example.
I'm new in Powershell and have find lots of things out but that. I don't know.
$File=Import-Csv '.\Datenbank\Hamburg.csv' -Delimiter ";" -Encoding UTF8 | foreach-object {
$Mtl1 = ""
$Mtl2 = ""
$Mtl3 = ""
$Org1 = ""
$Org2 = ""
$Org3 = ""
$Nummer = $_.Nummer
$User = ""
$Ordner1 = $_.Ordner1
$Ordner2 = $_.Ordner2
$Ordner3 = $_.Ordner3
$Beschreibung = $_.Gruppenbeschreibung
$Beschreibung2 = $_.Gruppenbeschreibung2
if ($Ordner1 -ne '') {$Org1 = echo HH}
if ($Ordner2 -ne '') {$Org2 = $($_.'Ordner2')}
if ($Ordner3 -ne '') {$Org3 = $($_.'Ordner3')}
$Mtl1 = "$Org1"
$Mtl2 = "$Org1" + "-" + "$Org2"
$Mtl3 = "$Org1" + "-" + "$Org2" + "-" + "$Org3"
#Lesen
$Mitgliedlesen3 = ""
$Mitgliedlesen2 = ""
$MitgliedÄndern3 = ""
$MitgliedÄndern2 = ""
$Bes = $_.Beschreibung
if ($Org3 -ne '') {$Mitgliedlesen3 = $Mtl3 + "-"+ "Lesen"}
if ($Org2 -ne '') {$Mitgliedlesen2 = $Mtl2 + "-" + "Lesen"}
$MitgliedÄndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bundesleiter"
$MitgliedÄndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array = $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3
$array2 = "leiter" , ""
have tested follow things.
#$array3 = (Compare-Object $array2 $array).InputObject
#$Array4 = $Array | where {$_ -match "leiter"}
$result = $array | Where {$array -notContains "leiter"}
#$result = $array1 | ?{$_.Split('=')[0] -in ($array2 | %{$_.Split('=')[0]})}
#$result = compare $Array $Array2 -Property Key -IncludeEqual -ExcludeDifferent -,
Passthru $result
#$Array -like "*$array2*"
#$Array4
#$array3[0..1]
#ForEach ($array in $array2){
#$array -replace "^[$i0 .. $i]$array2",""
#}
..
}
thanks for help.
I had some problems with the characters in your variables so I renamed them.
$MitgliedAndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bunde"
$MitgliedAndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array1 = #($MitgliedAndern2 , $Mitgliedlesen2 , $MitgliedAndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "Sekretär"
"array1 before before script runs: $array1`r"
for([int] $i = 0; $i -le ($array1.Count -1); $i++)
{
foreach($word in $array2)
{
if($array1[$i] -like "*$word*")
{
$array1[$i] = ""
}
}
}
"`rarray1 after script run: $array1`r"
the solution is this is my groundsolution:
$MitgliedÄndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bundespräsident"
$MitgliedÄndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array = #($MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "präsident"
"array1 before before script runs: $array`r"
for([int] $i = 0; $i -le ($array.Count -1); $i++)
{
foreach($word in $array2)
{
if($array[$i] -like "*$word*")
{
if ($array[$i] -match $MitgliedÄndern2) { if ($MitgliedÄndern2 -like "*$word*") {$MitgliedÄndern2 = ""}}
if ($array[$i] -match $Mitgliedlesen2) { if ($Mitgliedlesen2 -like "*$word*") {$Mitgliedlesen2 = ""} }
if ($array[$i] -match $MitgliedÄndern3) { if ($MitgliedÄndern3 -like "*$word*") {$MitgliedÄndern3 = ""} }
if ($array[$i] -match $Mitgliedlesen3) { if ($Mitgliedlesen3 -like "*$word*") {$Mitgliedlesen3 = ""} }
$array[$i] = ""
}
}
}
#$array[$i] = ""
"`rarray1 after script run: $array`r"
$MitgliedÄndern2
$Mitgliedlesen2
$MitgliedÄndern3
$Mitgliedlesen3

Error when executing SQL-Query from Powershell

I always get an error when executing this script:
Incorrect syntax near '#values'
I have the following function to execute my SQL statement:
$Server = "Server"
$Database = "Database"
$i = 0
function ExecuteSQLQuery(){
$Connection = New-Object System.Data.SqlClient.SqlConnection
$Connection.ConnectionString = "server='$Server';database='$Database'; trusted_connection=true;"
$Connection.Open()
$query = #
"INSERT INTO [Database].[dbo].[Folder](FolderPath,UserGroup,Permission,AccessControllType) VALUES #values
"#
$command = $connection.CreateCommand()
$command.CommandText = $query
$command.Parameters.Add("#values", $values)
$command.ExecuteNonQuery()
}
And this is the rest of the code in which I am getting the Data for the INSERT
$RootPath = "\\server\folder1\folder2\folder3"
$Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true}
#root folder permission
$ACLs = get-acl $RootPath | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs) {
#Add-Content -Value $OutInfo -Path $OutFile
$FolderPath = $RootPath
$User = $ACL.IdentityReference
$Permission = $ACL.FileSystemRights
$AccessControllType = $ACL.AccessControlType
if($i -gt 50) {
Invoke-sqlcmd #params -Query $InsertResult
$i=0
$values = ""
}
elseif($i -eq 0) {
$values += "('$FolderPath','$User','$Permission','$AccessControllType')"
$i ++
}
else {
$values += ",('$FolderPath','$User','$Permission','$AccessControllType')"
$i ++
}
}
#subfolders
foreach ($Folder in $Folders) {
$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs) {
$FolderPath = $Folder.Fullname
$User = $ACL.IdentityReference
$Permission = $ACL.FileSystemRights
$AccessControllType = $ACL.AccessControlType
$IsInherited = $ACL.IsInherited
if ($i -gt 50) {
ExecuteSQLQuery
$i=0
$values = ""
}
elseif ($i -eq 0) {
$values += "('$FolderPath','$User','$Permission','$AccessControllType')"
$i ++
}
else {
$values += ",('$FolderPath','$User','$Permission','$AccessControllType')"
$i ++
}
}
}
I am new to Powershell so I don't now if the error is because of my code or if the $values contains something Powershell or SQL can't handle.
Do you guys have any ideas?

New-Object : Cannot bind parameter 'Property'. Cannot convert the "" value of type PSCustomObject to type IDictionary

I'm having a hard time converting results from Invoke-SqlCmd to a PSCustomobject.
So, I input my query and SQL server, then I run the Invoke-SqlCmd function, and then I try to add data from that (the database logical name, and the autogrowth status) to my PSCustomobject, so I can return it back to my modules public function.
$sqlinstance = "---"
$query = "---"
if ($sqlInstance -match "---") {
$dbAutogrowIGP = Invoke-Sqlcmd -Query $query -ServerInstance $sqlInstance
if ($dbAutogrowIGP.Growth -gt 100 -and $dbAutogrowIGP.Growth -lt 500) {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $dbAutogrowIGP.LogicalName
'Check' = "Autogrow"
'Status' = "green"
'Status_reason' = ""
}
New-Object -Type Dictionary -Property $autogrowStatus
}
foreach ($db in $dbAutogrowIGP) {
if ($db.Growth -lt 100 -or $db.Growth -gt 500 -and $db.Growth -notlike "%") {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "red"
'Status_reason' = "$($db.LogicalName) has autogrowth set to $($db.Growth)."
}
New-Object -Type Dictionary -Property $autogrowStatus
}
if ($db.Growth -like "%") {
$autogrowStatus = [PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "yellow"
'Status_reason' = "$($db.LogicalName) has autogrowth set percentually, it should be an absolute number."
}
New-Object -Type Dictionary -Property $autogrowStatus
}
}
}
return $autogrowStatus
I've debugged it, and I've noticed it fails on the New-object call. I've tried both Dictionary and PSObject/PSCustomObject - however neither works
In my other functions, this works as expected, however in those, I'm using dbatools to make a call.
$getLogSizeIGP = Get-DbaDbLogSpace -sqlInstance $sqlInstance
if ($getLogSizeIGP.LogSize.Gigabyte -lt 10 -and $getLogSizeIGP.LogSpaceUsedPercent -lt 50) {
$logStatus = #{
'SQL_Instance' = $getLogSizeIGP.SqlInstance
'Check' = "Log_size"
'Status' = [gmEnvStatuses]::green
'Status_reason' = ""
}
New-Object -Type PSObject -Property $logStatus
}
How would I go about solving this issue?
This is the whole error message:
New-Object : Cannot bind parameter 'Property'. Cannot convert the "#{SQL_Instance=Maintenance_log; Check=Autogrow; Status=red; Status_reason=Maintenance_log has autogrowth set to 10%.}" value of type "System.Management.Automation.PSCustomObject" to type
"System.Collections.IDictionary".
At C:\Users\---\Desktop\autogrowth.ps1:50 char:55
+ New-Object -Type Dictionary -Property $autogrowStatus
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewObjectCommand
Thanks!
The easiest way of collecting this data is by capturing it all at the beginning of the if ($sqlInstance -match "---") { statement and simply output the PsCustomObjects without trying to convert them.
Something like
$sqlinstance = "---"
$query = "---"
$autogrowStatus = if ($sqlInstance -match "---") {
$dbAutogrowIGP = Invoke-Sqlcmd -Query $query -ServerInstance $sqlInstance
if ($dbAutogrowIGP.Growth -gt 100 -and $dbAutogrowIGP.Growth -lt 500) {
# output the object to be captured in the $autogrowStatus variable
[PSCustomObject]#{
'SQL_Instance' = $dbAutogrowIGP.LogicalName
'Check' = "Autogrow"
'Status' = "green"
'Status_reason' = ""
}
}
foreach ($db in $dbAutogrowIGP) {
if ($db.Growth -lt 100 -or $db.Growth -gt 500 -and $db.Growth -notlike "%") {
[PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "red"
'Status_reason' = "$($db.LogicalName) has autogrowth set to $($db.Growth)."
}
}
if ($db.Growth -like "%") {
[PSCustomObject]#{
'SQL_Instance' = $db.LogicalName
'Check' = "Autogrow"
'Status' = "yellow"
'Status_reason' = "$($db.LogicalName) has autogrowth set percentually, it should be an absolute number."
}
}
}
}
return $autogrowStatus
The variable $autogrowStatus will become an array of PSCustomObjects to handle in the rest of your functions.
Hope this helps

PowerShell Winforms Textbox updates on other input but overwriteable

Afternoon all,
I wanna believe this one is pretty easy but hitting a wall and can't figure out why.
I have a PowerShell winform that's going to create a new user account from a template. One of the fields I'm working on now is the line manager; once a template account has been found, auto-fill the line manager field, but allow it to be overwritten if this is incorrect.
For the pre-populated stuff I've been using:
$FORMCONTROL.Add_TextChanged( {
However once the template has been found and the line manager field written too, I can't overwrite it. Is there another Event I should be using to populate the box but allow me to delete the content and add something else?
The code below is a much cut down version of what I'm using. The functions allow for finding a user account and populating the ReadOnly box.
Function FindUser {
IF ( $SEARCHUSER -like $NULL -or $SEARCHUSER -like " *" )
{ }
ELSEIF ( $ACCOUNT = dsquery user -samid $SEARCHUSER )
{ $ACCOUNT = Get-ADUser $SEARCHUSER -Property * }
ELSEIF ( $ACCOUNT = Get-ADUser -Filter { mail -eq $SEARCHUSER } -ea sil )
{ $ACCOUNT = Get-ADUser -Filter { mail -eq $SEARCHUSER } -Property * }
ELSEIF ( dsquery user -name $SEARCHUSER )
{ $ACCOUNT = Get-ADUser -Filter { name -eq $SEARCHUSER } -Property * }
ELSE
{ $( foreach ( $SEARCHUSER in ( Get-ADUser -Filter { ( Surname -like $SEARCHUSER ) -and ( Enabled -eq $TRUE )
} -Properties Mail, Department, Office | sort Name ) )
{ $SEARCHUSER | Select Name, #{ N = "Username" ; E = { $_.SamAccountName } }, Mail, Department, Office
} ) | Out-GridView -Title 'Select the user account' -OutputMode Single | %{
TRY
{ $ACCOUNT = Get-ADUser $_.UserName -Property * }
CATCH
{ } } }
IF ( ( $ACCOUNT.SamAccountName ).count -eq 1 )
{ $Script:ACCOUNT = $ACCOUNT }
ELSE
{ $Script:ACCOUNT = $NULL } }
Function TemplateUser {
IF ( $ACCOUNT -ne $NULL )
{ $TAB1TEMPLATE_5.Text = ( $ACCOUNT.Name ) }
ELSEIF ( $TAB1TEMPLATE_3.Text.Length -lt 4 )
{ $TAB1TEMPLATE_5.Text = $NULL } }
# Creates the parent form and controls
$SDC = New-Object System.Windows.Forms.Form
$SDC.Location = New-Object System.Drawing.Size( 270,175 )
$SDC.Size = New-Object System.Drawing.Size( 900,600 )
$SDC.StartPosition = "CenterScreen"
$SDC.BackColor = "Lavender"
$SDC.Font = "Calibri, 8.5"
$SDC.FormBorderStyle = "Fixed3D"
#Tab 1 Template Account Label
$TAB1TEMPLATE_2 = New-Object System.Windows.Forms.Label
$TAB1TEMPLATE_2.Location = '35,90'
$TAB1TEMPLATE_2.Size = '200,20'
$TAB1TEMPLATE_2.Font = New-Object System.Drawing.Font( "Calibri",10,[System.Drawing.FontStyle]::Bold )
$TAB1TEMPLATE_2.Text = "Who are we using as a template?"
$SDC.Controls.Add( $TAB1TEMPLATE_2 )
#Tab 1 Template Textbox
$TAB1TEMPLATE_3 = New-Object System.Windows.Forms.TextBox
$TAB1TEMPLATE_3.Location = '20,115'
$TAB1TEMPLATE_3.Size = '200,20'
$TAB1TEMPLATE_3.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1TEMPLATE_3 )
#Tab 1 Template Textbox - When hit Return
$TAB1TEMPLATE_3.Add_KeyDown( {
IF ( $_.KeyCode -eq 'Enter' )
{ $SEARCHUSER = $TAB1TEMPLATE_3.Text ; FindUser ; TemplateUser } } )
#Tab 1 Template Account's Full Name
$TAB1TEMPLATE_5 = New-Object System.Windows.Forms.TextBox
$TAB1TEMPLATE_5.Location = '20,150'
$TAB1TEMPLATE_5.Size = '200,20'
$TAB1TEMPLATE_5.ReadOnly = $TRUE
$TAB1TEMPLATE_5.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1TEMPLATE_5 )
#Tab 1 Line Manager Label
$TAB1MANAGER_2 = New-Object System.Windows.Forms.Label
$TAB1MANAGER_2.Location = '35,400'
$TAB1MANAGER_2.Name = "Manager"
$TAB1MANAGER_2.Size = '245,20'
$TAB1MANAGER_2.Font = New-Object System.Drawing.Font( "Calibri",10,[System.Drawing.FontStyle]::Bold )
$TAB1MANAGER_2.Text = "Line Manager"
$SDC.Controls.Add( $TAB1MANAGER_2 )
#Tab 1 Line Manager Textbox
$TAB1MANAGER_3 = New-Object System.Windows.Forms.TextBox
$TAB1MANAGER_3.Location = '20,420'
$TAB1MANAGER_3.Size = '245,20'
$TAB1MANAGER_3.Name = "Manager"
$TAB1MANAGER_3.Font = New-Object System.Drawing.Font( "Calibri",9 )
$SDC.Controls.Add( $TAB1MANAGER_3 )
$TAB1MANAGER_3.Text = $( If ( $TAB1TEMPLATE_3.text -eq $NULL ) { "hi" } )
$SDC.ShowDialog()
I appear to have fixed it by editing the Function TemplateUser:
Function TemplateUser {
IF ( $ACCOUNT -ne $NULL )
{ $TAB1TEMPLATE_5.Text = ( $ACCOUNT.Name )
$TAB1MANAGER_3.Text = ( Get-ADUser $ACCOUNT.Manager ).Name
}
ELSEIF ( $TAB1TEMPLATE_3.Text.Length -lt 4 )
{ $TAB1TEMPLATE_5.Text = $NULL } }
Lord knows what I was doing wrong in the first place as didn't save the changes.
#TheIncorrigible1 - Curious to know what you mean by the formatting. Genuinely. Is there a more efficient way of writing? I'm aware that when complete this script is going to be pretty big so if I'm using unnecessary code I'm all ears.

Powershell Add_CheckStateChanged in an array of checkboxes

In a tab of my form, I show as much checkbox as I have scheduled tasks with specifics labels. Below, I have a button which is disabled, and I want it enabled only if I have at least one of the checkbox checked.
So I add a "Add_CheckStateChanged" but it activate the button only with the last checkbox. When I check among the firsts checkboxes, it does nothing with the button.
Here is the part of script:
function getTasks($path) {
$out = #()
$schedule.GetFolder($path).GetTasks(0) | % {
$xml = [xml]$_.xml
$out += New-Object psobject -Property #{
"Name" = $_.Name
"Path" = $_.Path
"LastRunTime" = $_.LastRunTime
"NextRunTime" = $_.NextRunTime
"Actions" = ($xml.Task.Actions.Exec | % { "$($_.Command) $($_.Arguments)" }) -join "`n"
}
}
$schedule.GetFolder($path).GetFolders(0) | % {
$out += getTasks($_.Path)
}
$out
}
$tasks = #()
$schedule = New-Object -ComObject "Schedule.Service"
$schedule.Connect()
$tasks += getTasks("\")
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
Remove-Variable schedule
$tasksMySoft = $tasks | Where-Object {$_.Name -match "MySoft1|MySoft2|MySoft3|MySoft4|MySoft5|MySoft6"}
$CheckBoxLabels = $tasksMySoft.name
$CheckBoxCounter = 1
$CheckBoxes = foreach($taskLabel in $CheckBoxLabels) {
$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0
$CheckBox.UseVisualStyleBackColor = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 175
$System_Drawing_Size.Height = 20
$CheckBox.Size = $System_Drawing_Size
$CheckBox.TabIndex = 2
$CheckBox.Text = $taskLabel
$System_Drawing_Point = New-Object System.Drawing.Point
if($CheckBoxCounter -lt 9){
$System_Drawing_Point.X = 90}
elseif($CheckBoxCounter -ge 9){
$System_Drawing_Point.X = 275}
if($CheckBoxCounter -lt 9){
$System_Drawing_Point.Y = 45 + (($CheckBoxCounter - 1) * 20)}
elseif($CheckBoxCounter -ge 9){
$System_Drawing_Point.Y = - 115 + (($CheckBoxCounter - 1) * 20)}
$CheckBox.Location = $System_Drawing_Point
$CheckBox.Name = "CheckBox$CheckBoxCounter"
$CheckBox.Add_CheckStateChanged({
if($CheckBox.checked -eq $True){
$GenerateButton.Enabled = $true
}else{
$GenerateButton.Enabled = $false}
})
$tab.Controls.Add($CheckBox)
$CheckBox
$CheckBoxCounter++
}
Some help would be nice ;)
I found on my own. I replaced
$CheckBox.Add_CheckStateChanged({
if($CheckBox.checked -eq $True){
$GenerateButton.Enabled = $true
}else{
$GenerateButton.Enabled = $false}
})
by
$CheckBox.Add_CheckStateChanged({
foreach($CheckBox in $CheckBoxes | Where-Object {$_.checked -eq $false}) {
$GenerateButton.Enabled = $false}
})
$CheckBox.Add_CheckStateChanged({
foreach($CheckBox in $CheckBoxes | Where-Object {$_.checked -eq $true}) {
$GenerateButton.Enabled = $true}
})

Resources