So after succeeding in passing variables to start-job(huge thanks to the awesome stackoverflow members).
Now I'm struggling to pass a function into the job.
I need to use the Append-ColoredLine function inside the 7zipextraction job.
For some reason I cant find a way of achieving that.
function Append-ColoredLine
{
param (
[Parameter(Mandatory = $true, Position = 0)]
[System.Windows.Forms.RichTextBox]$box,
[Parameter(Mandatory = $true, Position = 1)]
[System.Drawing.Color]$color,
[Parameter(Mandatory = $true, Position = 2)]
[string]$text
)
$box.SelectionStart = $box.TextLength
$box.SelectionLength = 0
$box.SelectionColor = $color
$box.AppendText($text)
$box.AppendText([Environment]::NewLine)
}
$OutputDirectory="C:\Test\2"
$zipfile="C:\Test\2\1.zip"
$uploadevidence="C:\UploadFolder"
function 7zipextraction
{
Set-Alias 7zip $using:7zip_path
# Extracting files
$extract = 7zip x -y $using:zpfile -o"${using:OutputDirectory}"
if ($LASTEXITCODE -ne 0)
{
Append-ColoredLine $using:richtextbox1 Red "$using:Time 7zip Error"
return
}
else
{
Append-ColoredLine $using:richtextbox1 Blue "$using:Time Files extracted successfully"
}
Start-Sleep -s 2
}
Start-Job -Name zip2 -ScriptBlock ${Function:7zipextraction} | Receive-Job -Wait
I have an arraylist filled with data from a cmdlet (from the BEMCLI module) and want to store the data in a database. Declaring every column is just to specify the error.
There are some questions about a similar error code but I don't know how to get the solution work for me.
Errorcode:
No mapping exists from object type System.Data.Arraylist to a known managed
provider native type
In C:\**\test.ps1:68 Zeichen:1
+ $SqlCmd.executenonquery()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
Script:
$JobHistory = Invoke-Command -ComputerName $ServerName -ScriptBlock {
Import-Module BEMCLI;
Get-BEJobHistory -FromStartTime (Get-Date).AddDays(-1)
}
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True;"
$SqlConnection.Open()
for ($i=0; $i -lt $JobHistory.Length; $i++) {
$SqlCmd.Parameters.Add("#Name", [System.Data.SqlDbType]::string).Value = $JobHistory[$i].Name
$SqlCmd.Parameters.Add("#ID", [System.Data.SqlDbType]::UniqueIdentifier).Value = $JobHistory[$i].ID
$SqlCmd.Parameters.Add("#JobName", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].JobName
$SqlCmd.Parameters.Add("#JobStatus", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].JobStatus
$SqlCmd.Parameters.Add("#Job", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].Job
$SqlCmd.Parameters.Add("#JobId", [System.Data.SqlDbType]::UniqueIdentifier).Value = $JobHistory[$i].JobId
$SqlCmd.Parameters.Add("#JobType", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].JobType
$SqlCmd.Parameters.Add("#StartTime", [System.Data.SqlDbType]::DateTime).Value = $JobHistory[$i].StartTime
$SqlCmd.Parameters.Add("#ElapsedTime", [System.Data.SqlDbType]::TimeSpan).Value = $JobHistory[$i].ElapsedTime
$SqlCmd.Parameters.Add("#EndTime", [System.Data.SqlDbType]::DateTime).Value = $JobHistory[$i].EndTime
$SqlCmd.Parameters.Add("#PercentComplete", [System.Data.SqlDbType]::Real).Value = $JobHistory[$i].PercentComplete
$SqlCmd.Parameters.Add("#AgentServer", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].AgentServer
$SqlCmd.Parameters.Add("#AgentServerIdList", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].AgentServerIdList
$SqlCmd.Parameters.Add("#BackupExecServerName", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].JobLogFilePath
$SqlCmd.Parameters.Add("#JobLogFilePath", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].JobLogFilePath
$SqlCmd.Parameters.Add("#DeduplicationRatio", [System.Data.SqlDbType]::Real).Value = $JobHistory[$i].DeduplicationRatio
$SqlCmd.Parameters.Add("#JobRateMBPerMinute", [System.Data.SqlDbType]::Real).Value = $JobHistory[$i].JobRateMBPerMinute
$SqlCmd.Parameters.Add("#StorageName", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].StorageName
$SqlCmd.Parameters.Add("#TotalDataSizeBytes", [System.Data.SqlDbType]::BigInt).Value = $JobHistory[$i].TotalDataSizeBytes
$SqlCmd.Parameters.Add("#ErrorCategory", [System.Data.SqlDbType]::Int).Value = $JobHistory[$i].ErrorCategory
$SqlCmd.Parameters.Add("#ErrorCode", [System.Data.SqlDbType]::Int).Value = $JobHistory[$i].ErrorCode
$SqlCmd.Parameters.Add("#ErrorCategory", [System.Data.SqlDbType]::String).Value = $JobHistory[$i].ErrorCategory
$SqlCmd.Parameters.Add("#ErrorMessage", [System.Data.SqlDbType]::Int).Value = $JobHistory[$i].ErrorMessage
$SqlQuery = "INSERT INTO JobHistory(Nr,Name,ID,JobName,JobStatus,Job,JobId,JobType,StartTime,ElapsedTime,EndTime,PercentComplete,AgentServer,AgentServerIdList,BackupExecServerName,JobLogFilePath,DeduplicationRatio,JobRateMBPerMinute,StorageName,TotalDataSizeBytes,ErrorCategory,ErrorCode,ErrorCategory,ErrorMessage) VALUES (#Nr,#Name,#ID,#JobName,#JobStatus,#Job,#JobId,#JobType,#StartTime,#ElapsedTime,#EndTime,#PercentComplete,#AgentServer,#AgentServerIdList,#BackupExecServerName,#JobLogFilePath,#DeduplicationRatio,#JobRateMBPerMinute,#StorageName,#TotalDataSizeBytes,#ErrorCategory,#ErrorCode,#ErrorCategory,#ErrorMessage)"
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlCmd.ExecuteNonQuery()
}
Thanks to Richard for giving the right hint.
Collections cause the problem (AgentServer and AgentServerIdList)
i fixed the code from above, adding $SqlCmd.Parameters.Clear() in the loop to clear the parameters in every loop. It was something like 'cannot declare #Variable twice'.
Commandline gave me another error - so i decided to switch to .Parameters.AddWithValue-Command.
Script works fine now. Thank you!
$JobHistory = invoke-command -ComputerName $ServerName -ScriptBlock { import-module BEMCLI; Get-BEJobHistory -FromStartTime (get-date).AddDays(-1) }
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True;"
$SqlCmd.Connection = $SqlConnection
$SqlConnection.Open()
for($i=0; $i -lt $JobHistory.Length; $i++){
$SqlCmd.Parameters.Clear()
$SqlCmd.Parameters.AddWithValue("#Nr", $JobHistory[$i].Nr)
$SqlCmd.Parameters.AddWithValue("#Name",$JobHistory[$i].Name)
$SqlCmd.Parameters.AddWithValue("#ID", $JobHistory[$i].ID)
$SqlCmd.Parameters.AddWithValue("#JobName", $JobHistory[$i].JobName)
$SqlCmd.Parameters.AddWithValue("#JobStatus", $JobHistory[$i].JobStatus)
$SqlCmd.Parameters.AddWithValue("#Job", $JobHistory[$i].Job)
$SqlCmd.Parameters.AddWithValue("#JobId", $JobHistory[$i].JobId)
$SqlCmd.Parameters.AddWithValue("#JobType", $JobHistory[$i].JobType)
$SqlCmd.Parameters.AddWithValue("#StartTime", $JobHistory[$i].StartTime)
$SqlCmd.Parameters.AddWithValue("#ElapsedTime", $JobHistory[$i].ElapsedTime)
$SqlCmd.Parameters.AddWithValue("#EndTime", $JobHistory[$i].EndTime)
$SqlCmd.Parameters.AddWithValue("#PercentComplete", $JobHistory[$i].PercentComplete)
$SqlCmd.Parameters.AddWithValue("#BackupExecServerName", $JobHistory[$i].BackupExecServerName)
$SqlCmd.Parameters.AddWithValue("#JobLogFilePath", $JobHistory[$i].JobLogFilePath)
$SqlCmd.Parameters.AddWithValue("#DeduplicationRatio", $JobHistory[$i].DeduplicationRatio)
$SqlCmd.Parameters.AddWithValue("#JobRateMBPerMinute", $JobHistory[$i].JobRateMBPerMinute)
$SqlCmd.Parameters.AddWithValue("#StorageName", $JobHistory[$i].StorageName)
$SqlCmd.Parameters.AddWithValue("#TotalDataSizeBytes", $JobHistory[$i].TotalDataSizeBytes)
$SqlCmd.Parameters.AddWithValue("#ErrorCode", $JobHistory[$i].ErrorCode)
$SqlCmd.Parameters.AddWithValue("#ErrorCategory", $JobHistory[$i].ErrorCategory)
$SqlCmd.Parameters.AddWithValue("#ErrorCategoryType", $JobHistory[$i].ErrorCategoryType)
$SqlCmd.Parameters.AddWithValue("#ErrorMessage", $ValueForJobHistory[$i].ErrorMessage)
$SqlQuery = "Insert into JobHistory(Nr,Name,ID,JobName,JobStatus,Job,JobId,JobType,StartTime,ElapsedTime,EndTime,PercentComplete,BackupExecServerName,JobLogFilePath,DeduplicationRatio,JobRateMBPerMinute,StorageName,TotalDataSizeBytes,ErrorCode,ErrorCategory,ErrorCategoryType) Values(#Nr,#Name,#ID,#JobName,#JobStatus,#Job,#JobId,#JobType,#StartTime,#ElapsedTime,#EndTime,#PercentComplete,#BackupExecServerName,#JobLogFilePath,#DeduplicationRatio,#JobRateMBPerMinute,#StorageName,#TotalDataSizeBytes,#ErrorCode,#ErrorCategoryType,#ErrorCategory)"
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.executenonquery()
}
I am using the MySQL connector with PowerShell and I have the need to do a query, then scrub the data a little bit and then dump the remainder to another table on the same MySQL DB. How could I leave the connection open to make this all run a bit faster?
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection)
$DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command)
$DataSet = New-Object System.Data.DataSet
$RecordCount = $dataAdapter.Fill($dataSet, "data")
return $DataSet.Tables[0]
Create the connection object in the function that calls this function. The called function will inherit whatever objects the calling function is maintaining, so $Connection will be valid in the called function.
function RunMe(){
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
# Call the function that executes the MySQL code
ExecuteMySQL
# If needed, call another function that executes the MySQL code
ExecuteSomeOtherMySQL
# Close the connection after all MySQL operations are complete
$Connection.Close()
}
function ExecuteMySQL(){
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection)
$DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command)
$DataSet = New-Object System.Data.DataSet
$RecordCount = $dataAdapter.Fill($dataSet, "data")
return $DataSet.Tables[0]
}
Trying to write a function to create a new line to be added to a table for export. The following outputs the correct values to the console but the CSV is empty.
If I place the code to create $newline at various point in the script it works fine but not when I call it as a function.
$report = #()
Function CreateNewLine
{
$lineproperties = #{
Cluster = $cluster
Node = $node
Database = $d.Name
LogCount = $logcount
LogPath = $p
}
$newline = New-Object PSObject -property $lineproperties
}
# Loop to create values for $cluster etc...
CreateNewLine
$report += $newline
# End loop
$report | Export-CSV 'pathto file' -notype
You have a scope issue here. $newline has no context outside the function. Therefore you would just be adding $null to the $report array. Make the function return the value which can then be captured.
Function CreateNewLine
{
$lineproperties = #{
Cluster = $cluster
Node = $node
Database = $d.Name
LogCount = $logcount
LogPath = $p
}
New-Object PSObject -property $lineproperties
}
# Loop to create values for $cluster etc...
$report += CreateNewLine
The function should have access to those other variables as long as they are in the parent scope of the function.
The function CreateNewLine never returns a value. You need to do the following:
Function CreateNewLine
{
$lineproperties = [PSCustomObject]#{
Cluster = $cluster
Node = $node
Database = $d.Name
LogCount = $logcount
LogPath = $p
}
$lineProperties
}
You can create an object in much easier manner (as Matt said, this works in Powershell 3.0 and later):
Function CreateNewLine
{
[pscustomobject]#{
Cluster = $cluster
Node = $node
Database = "name"
LogCount = $logcount
LogPath = $p
}
}
Then, in any place you want you can use this function:
$cluster = "cluster 1"
$report += createnewline
$cluster = "cluster 2"
$report += createnewline
$report | Export-CSV 'pathto file' -notype
I would like to automatically script out all SQL Server 2008 policies and conditions on a server each night and compare the files to my version control system. In the UI, I can script out individual policies by right-clicking the policy and selecting Export Policy. Is it possible to script out policies and conditions via SMO or PowerShell?
Ideally, I would like to incorporate this into my existing PowerShell script that generates scripts for all of my other server and database objects. Here's the script that currently does this action:
# Load needed assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended")| Out-Null;
#Specify target server and databases.
$sql_server = "SomeServerName"
$SMOserver = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList "$sql_server"
$databases = $SMOserver.Databases
$BaseSavePath = "T:\SomeFilePath\" + $sql_server + "\"
#Remove existing objects.
Remove-Item $BaseSavePath -Recurse
#Script server-level objects.
$ServerSavePath = $BaseSavePath
$ServerObjects = $SMOserver.BackupDevices
$ServerObjects += $SMOserver.Endpoints
$ServerObjects += $SMOserver.JobServer.Jobs
$ServerObjects += $SMOserver.LinkedServers
$ServerObjects += $SMOserver.Triggers
foreach ($ScriptThis in $ServerObjects | where {!($_.IsSystemObject)})
{
#Need to Add Some mkDirs for the different $Fldr=$ScriptThis.GetType().Name
$scriptr = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SMOserver)
$scriptr.Options.AppendToFile = $True
$scriptr.Options.AllowSystemObjects = $False
$scriptr.Options.ClusteredIndexes = $True
$scriptr.Options.DriAll = $True
$scriptr.Options.ScriptDrops = $False
$scriptr.Options.IncludeHeaders = $False
$scriptr.Options.ToFileOnly = $True
$scriptr.Options.Indexes = $True
$scriptr.Options.Permissions = $True
$scriptr.Options.WithDependencies = $False
<#Script the Drop too#>
$ScriptDrop = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SMOserver)
$ScriptDrop.Options.AppendToFile = $True
$ScriptDrop.Options.AllowSystemObjects = $False
$ScriptDrop.Options.ClusteredIndexes = $True
$ScriptDrop.Options.DriAll = $True
$ScriptDrop.Options.ScriptDrops = $True
$ScriptDrop.Options.IncludeHeaders = $False
$ScriptDrop.Options.ToFileOnly = $True
$ScriptDrop.Options.Indexes = $True
$ScriptDrop.Options.WithDependencies = $False
<#This section builds folder structures. Remove the date folder if you want to overwrite#>
$TypeFolder=$ScriptThis.GetType().Name
if ((Test-Path -Path "$ServerSavePath\$TypeFolder") -eq "true") `
{"Scripting Out $TypeFolder $ScriptThis"} `
else {new-item -type directory -name "$TypeFolder"-path "$ServerSavePath"}
$ScriptFile = $ScriptThis -replace ":", "-" -replace "\\", "-"
$ScriptDrop.Options.FileName = $ServerSavePath + "\" + $TypeFolder + "\" + $ScriptFile.Replace("]", "").Replace("[", "") + ".sql"
$scriptr.Options.FileName = $ServerSavePath + "\" + $TypeFolder + "\" + $ScriptFile.Replace("]", "").Replace("[", "") + ".sql"
#This is where each object actually gets scripted one at a time.
$ScriptDrop.Script($ScriptThis)
$scriptr.Script($ScriptThis)
} #This ends the object scripting loop at the server level.
#Script database-level objects.
foreach ($db in $databases)
{
$DatabaseObjects = $db.ApplicationRoles
$DatabaseObjects += $db.Assemblies
$DatabaseObjects += $db.ExtendedStoredProcedures
$DatabaseObjects += $db.ExtendedProperties
$DatabaseObjects += $db.PartitionFunctions
$DatabaseObjects += $db.PartitionSchemes
$DatabaseObjects += $db.Roles
$DatabaseObjects += $db.Rules
$DatabaseObjects += $db.Schemas
$DatabaseObjects += $db.StoredProcedures
$DatabaseObjects += $db.Synonyms
$DatabaseObjects += $db.Tables
$DatabaseObjects += $db.Triggers
$DatabaseObjects += $db.UserDefinedAggregates
$DatabaseObjects += $db.UserDefinedDataTypes
$DatabaseObjects += $db.UserDefinedFunctions
$DatabaseObjects += $db.UserDefinedTableTypes
$DatabaseObjects += $db.UserDefinedTypes
$DatabaseObjects += $db.Users
$DatabaseObjects += $db.Views
#Build this portion of the directory structure out here. Remove the existing directory and its contents first.
$DatabaseSavePath = $BaseSavePath + "Databases\" + $db.Name
new-item -type directory -path "$DatabaseSavePath"
foreach ($ScriptThis in $DatabaseObjects | where {!($_.IsSystemObject)})
{
#Need to Add Some mkDirs for the different $Fldr=$ScriptThis.GetType().Name
$scriptr = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SMOserver)
$scriptr.Options.AppendToFile = $True
$scriptr.Options.AllowSystemObjects = $False
$scriptr.Options.ClusteredIndexes = $True
$scriptr.Options.DriAll = $True
$scriptr.Options.ScriptDrops = $False
$scriptr.Options.IncludeHeaders = $False
$scriptr.Options.ToFileOnly = $True
$scriptr.Options.Indexes = $True
$scriptr.Options.Permissions = $True
$scriptr.Options.WithDependencies = $False
<#Script the Drop too#>
$ScriptDrop = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SMOserver)
$ScriptDrop.Options.AppendToFile = $True
$ScriptDrop.Options.AllowSystemObjects = $False
$ScriptDrop.Options.ClusteredIndexes = $True
$ScriptDrop.Options.DriAll = $True
$ScriptDrop.Options.ScriptDrops = $True
$ScriptDrop.Options.IncludeHeaders = $False
$ScriptDrop.Options.ToFileOnly = $True
$ScriptDrop.Options.Indexes = $True
$ScriptDrop.Options.WithDependencies = $False
<#This section builds folder structures. Remove the date folder if you want to overwrite#>
$TypeFolder=$ScriptThis.GetType().Name
if ((Test-Path -Path "$DatabaseSavePath\$TypeFolder") -eq "true") `
{"Scripting Out $TypeFolder $ScriptThis"} `
else {new-item -type directory -name "$TypeFolder"-path "$DatabaseSavePath"}
$ScriptFile = $ScriptThis -replace ":", "-" -replace "\\", "-"
$ScriptDrop.Options.FileName = $DatabaseSavePath + "\" + $TypeFolder + "\" + $ScriptFile.Replace("]", "").Replace("[", "") + ".sql"
$scriptr.Options.FileName = $DatabaseSavePath + "\" + $TypeFolder + "\" + $ScriptFile.Replace("]", "").Replace("[", "") + ".sql"
#This is where each object actually gets scripted one at a time.
$ScriptDrop.Script($ScriptThis)
$scriptr.Script($ScriptThis)
} #This ends the object scripting loop.
} #This ends the database loop.
You have a couple of choices from SMO/Powershell.
1: SQLPS/PowerShell with SQL loaded
SQLSERVER:\SQLPolicy\\DEFAULT\Policies
you can then dig through it, i didnt see an "export" but you can certianly get the info out of it.
2: SMO
basically SMO has a Microsoft.SqlServer.Management.DMF namespace that has severial policy objects (what you end up with in the PowerShell side of things) Policy, PolicyStore, PolicyCondition etc, rather than write out an example, you can find one here.
http://rdbmsexperts.com/Blogs/archives/295
again i didnt see an "export" method anywhere, but you could probably spit out what you needed easily enough.