How Can I pass multiple VBA variables into a called Powershell script? - vba

Can I pass a VBA variable into a called Powershell script?.
With the help of the above post, I am able to pass one variable to PowerShell. I need to pass two variables, there I failed with the below script. Can someone please help me with it.
strCommand = "powershell -ExecutionPolicy Unrestricted -file `\""C:\Users\n3540551\Desktop\cluster\remote.ps1`\"" -name `\""" & nameVariable & "`\"" -pass2 `\""" & passVariable & "`\"""
PowerShell script as below:-
param([string]$name)
param([string]$pass2)
$MyUserName = "cctv";
$MyPassword = ConvertTo-SecureString $pass2 -asplaintext -force;
$MyCredentials2 = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $MyUserName,$MyPassword
$scriptblock = {if ((Select-String -Path "C:\ProgramData\Root.1.log" -Pattern "Mismatching SRP verifier") -ne $null){echo "Mismatching SRP verifier found. Please check File"}else{ echo "All Goood!"}}
Invoke-Command -ComputerName $name -credential $MyCredentials2 -ScriptBlock $scriptblock

The PowerShell parser only recognizes 1 param statement per block, so you need to change:
param([string]$name)
param([string]$pass2)
to
param(
[string]$name,
[string]$pass2
)

Related

PowerShell 7. ForEach-Object -Parallel Does Not Autheticate Against Azure PowerShell

We wrote a script that supposed to execute Azure PowerShell commands in parallel. The problem is when we increase -ThrottleLimit higher than one, some of the commands are not being performed properly. The script is:
# Writing IPs for whitelisting into file.
Add-Content -Path IPs.txt -Value ((Get-AzWebApp -ResourceGroupName "ResourceGroup1" -Name "WebApp1").OutboundIpAddresses).Split(",")
Add-Content -Path IPs.txt -Value ((Get-AzWebApp -ResourceGroupName "ResourceGroup1" -Name "WebApp1").PossibleOutboundIpAddresses).Split(",")
# Writing new file with inique IPs.
Get-Content IPs.txt | Sort-Object -Unique | Set-Content UniqueIPs.txt
# Referencing the file.
$IPsForWhitelisting = Get-Content UniqueIPs.txt
# Assigning priotiry number to each IP
$Count = 100
$List = foreach ($IP in $IPsForWhitelisting) {
$IP|Select #{l='IP';e={$_}},#{l='Count';e={$Count}}
$Count++
}
# Whitelisting all the IPs from the list.
$List | ForEach-Object -Parallel {
$IP = $_.IP
$Priority = $_.Count
$azureApplicationId ="***"
$azureTenantId= "***"
$azureApplicationSecret = "***"
$azureSecurePassword = ConvertTo-SecureString $azureApplicationSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($azureApplicationId , $azureSecurePassword)
Connect-AzAccount -Credential $credential -TenantId $azureTenantId -ServicePrincipal | Out-null
echo "IP-$Priority"
echo "$IP/24"
echo $Priority
Add-AzWebAppAccessRestrictionRule -ResourceGroupName "ResourceGroup1" -WebAppName "WebApp1" -Name "IP-$Priority" -Priority $Priority -Action Allow -IpAddress "$IP/24"
} -ThrottleLimit 1
If ThrottleLimit is set to 1 - 8 rules are being created, if ThrottleLimit is set to 2 - 7 rules are being created, 3 - 4 rules, 10 - 1 rule, hence some rules are being skipped.
What is the reason for such behavior?
In short - the -Parallel parameter does not (yet perhaps) magically import all dependent variables that fall in the scope of the For-EachObject block. In reality PWSH spans separate processes and only the array that is looped over will be implicitly passed, all other variables need explicit designations.
One should use the $using: directive (prefix) to denote which variables are to be imported (made visible) in the parallel code block.
Example:
$avar = [Int]10
$bvar = [Int]20
$list = #('here', 'it', 'eees')
$list | ForEach-Object -Parallel {
Write-Output "(a, b) is here ($($using:avar), $($using:bvar))"
Write-Output "(a, b) missing ($($avar), $($bvar))"
Write-Output "Current element is $_"
}```
*thus - the described behavior is likely due to the fact that config. variables are not imported (at all) and thus the operations silently fail.*

Invoke-AzVMRunCommand as a job

I am trying to use Invoke-AzVMRunCommand as a job. when I executed below script the job is created and executed successfully but I am failing to write the output like which job result belongs to which vm.
Invoke-AzVMRunCommand is used to invoke a command on a particular VM. You should have this information beforehand.
Here is some information on -AsJob parameter
https://learn.microsoft.com/en-us/powershell/module/az.compute/invoke-azvmruncommand?view=azps-2.6.0#parameters
As suggested by AmanGarg-MSFT, you should have that information before hand. You can use a hashtable $Jobs to store the server name and Invoke-AzVMRunCommand output and later iterate through using the $Jobs.GetEnumerator().
$Jobs = #{}
$Servers = "Server01","Server02"
[System.String]$ScriptBlock = {Get-Process}
$FileName = "RunScript.ps1"
Out-File -FilePath $FileName -InputObject $ScriptBlock -NoNewline
$Servers | ForEach-Object {
$vm = Get-AzVM -Name $_
$Jobs.Add($_,(Invoke-AzVMRunCommand -ResourceGroupName $vm.ResourceGroupName -Name $_ -CommandId 'RunPowerShellScript' -ScriptPath $FileName -AsJob))
}

Powershell: How to Parse the Multi line String as a String parameter?

As a newbie in powershell, im trying to read thru a folder which has multiple sql files and iterate them through poweshell scripts read the data from oracle and export to CSV.
If my sqlfile has a single line statement no issues with the code, its working fine, If my sql file has multiple line statement - as always it has,
the powershell errors out saying
"Get-DataTable : Cannot process argument transformation on parameter 'sql' Cannot convert value to type System.String."
could you please help me how to resolve this issue? Below my code snapshot.
function Get-DataTable{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[Oracle.DataAccess.Client.OracleConnection]$conn,
[Parameter(Mandatory=$true)]
[string]$sql
)
$cmd = New-Object Oracle.DataAccess.Client.OracleCommand($sql,$conn)
$da = New-Object Oracle.DataAccess.Client.OracleDataAdapter($cmd)
$dt = New-Object System.Data.DataTable
[void]$da.Fill($dt)
return ,$dt
}
foreach ($file in Get-ChildItem -path $ScriptsDirectory -Filter *.sql | sort-object -desc )
{
$SQLquery = get-content "$ScriptsDirectory\$file"
echo $SQLquery
$fileName = $file.name.split(".")[0]
$dt = Get-DataTable $conn $SQLquery
Write-Host "Retrieved records:" $dt.Rows.Count -ForegroundColor Green
$dt | Export-Csv -NoTypeInformation -LiteralPath $WorkingDirectory\$fileName.csv
Write-Host "Output Written to :" $WorkingDirectory\$fileName.csv -ForegroundColor Green }
Get-Content returns an array of lines. If you're using PowerShell v3 or higher you can use the -Raw parameter to read the file as one big string:
$SQLquery = get-content "$ScriptsDirectory\$file" -Raw
Alternatively you could re-join the array with line endings:
$SQLquery = $SQLquery -join "`r`n"
Or you can read the file all at once with .net classes:
$SQLquery = [System.IO.File]::ReadAllText("$ScriptsDirectory\$file")

Oracle Sql and Powershell : Execute query, print/output results

I need a way to execute a SQL (by importing a .SQL script) on a remote Oracle DB using PowerShell. In addition to this I am also trying to output the results in an .xls format in a desired folder location. To add to the fun, I would also want to run this task on an automatic schedule. Please help !
I have gotten so far :
[System.Reflection.Assembly]::LoadWithPartialName ("System.Data.OracleClient") | Out-Null
$connection = "my TNS entry"
$queryString = "my SQL query"
$command = new-Object System.Data.OracleClient.OracleCommand($queryString, $connection)
$connection.Open()
$reader = $command.ExecuteReader()
$tempArr = #()
#read all rows into a hash table
while ($reader.Read())
{
$row = #{}
for ($i = 0; $i -lt $reader.FieldCount; $i++)
{
$row[$reader.GetName($i)] = $reader.GetValue($i)
}
#convert hashtable into an array of PSObjects
$tempArr+= new-object psobject -property $row
}
$connection.Close()
write-host "Conn State--> " $connection.State
$tmpArr | Export-Csv "my File Path" -NoTypeInformation
$Error[0] | fl -Force
The easiest way is to drive sqlplus.exe via powershell. To execute the sql and get the output you do this:
$result = sqlplus.exe #file.sql [credentials/server]
#parse result into CSV here which can be loaded into excel
You can schedule this script with something like:
schtasks.exe /create /TN sqlplus /TR "Powershell -File script.ps1" /ST 10 ...
For this you need to have sqlplus installed (it comes with oracle express and you could install it without it). This obviously introduces dependency that is not needed but sqlplus could be used to examine the database and do any kind of thing which might be good thing to have around.

Running a script from a powershell script with conditions

So, I have a script I use for deployments and some of these commands aren't recognized till after sqlps is run, usually I do it manually. I want to automate the running of that script. Here is the script:
$client = Read-Host "Enter Client name"
$date = Get-Date -Format "yymmdd"
$sqlsrvname = Read-Host "Please enter the sql server name"
$deploytype = Read-Host "Is there a server instance? (1) Yes (2) No"
switch($deploytype){
1 {$Instance = Read-Host "Please Enter instance name"
cd -Path $ppath
Invoke-Command .\sqlpatchremote.ps1 -DBServer $sqlsrvname –dbinstance $Instance –client $client –mainline HTFS –datefolder $date –targetenv $sqlsrvname }
2 {cd -Path $ppath
Invoke-Command .\sqlpatchremote.ps1 –dbs $sqlsrvname –client $client –mainline HTFS –datefolder $date –targetenv $sqlsrvname }
default {"Invalid Selection"}
}
When I try to run this script I get this error:
Invoke-Command : A parameter cannot be found that matches parameter name 'DBServer'.
At line:17 char:38
+ Invoke-Command .\sqlpatchremote.ps1 -DBServer $sqlsrvname –dbinstance $Instance
...
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindi
ngException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.
InvokeCommandCommand
It tells me its an invalid command when it normally works when I type this in manually, how can I make this work? This script is suppose to install SQL databases on a SQL server. When I run this code manually I just type "sqlps" and then navigate to the directory of the script. Then I run it with the filled in parameters and it doesn't give me an error. I feel like this might be a simple fix to get this to work, but I'm not sure what it is and I wasn't really sure how to ask it. Thanks!
Error:
Invoke-Command : A parameter cannot be found that matches parameter name 'DBServer'.
At line:17 char:38
Invoke-Command rejects parameter DBServer. This means you are passing the arguments to Invoke-Command instead of your script.
To pass the arguments to the script you are invoking, you have to use the -ArgumentList parameter.
Try :
Invoke-Command -ComputerName "targethost" .\sqlpatchremote.ps1 -ArgumentList "-DBServer $sqlsrvname –dbinstance $Instance –client $client –mainline HTFS –datefolder $date –targetenv $sqlsrvname"
EDIT: really not sure about the above syntax for the arguments :( (if anyone could confirm?)
With the arguments in the proper order I've successfully tested it like this:
Invoke-Command -ComputerName "targethost" "scriptpath" -ArgumentList $arg1,$arg2#,...
MSDN