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
Related
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
)
This is my first time using Powershell so please forgive my ignorance.
I have a SQL query that returns back a bunch of order numbers. I want to check another file to see if there is an existing PDF in that file with the same name as the orders numbers returned by the SQL query.
Everything in my code works up until the ForEach loop which returns nothing. Based on my google searches I think I'm pretty close but I'm not sure what I'm doing wrong. Any help would be appreciated.
I've removed the actual file name for obvious reasons, and I do know that the file is correct and other commands do access it so I know that is not my problem at the moment. I've also removed sensitive info from the SQL query.
$statement = "SELECT A, Date FROM XXXX
WHERE STAT = 1 AND Date >= trunc(sysdate)"
$con = New-Object System.Data.OracleClient.OracleConnection($connection_string)
$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = $statement
$result = $cmd.ExecuteReader()
$list = while ($result.Read()) { $result["A"]}
Write-Output $list
#########Loop through the list above here to check for matching PDF
ForEach ($Order in $list){
Get-ChildItem "\\xxxxxx\" -Filter $Order -File
#########If FALSE - notify that PDF is missing
}
$con.close()
I have also tried the following code, which gets me closer and actually finds the files I'm looking for, but gives the error
" Get-ChildItem : A positional parameter cannot be found that accepts argument
CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand"
ForEach ($Order in $list){
if((Get-ChildItem "\\xxxxx\" + $Order)){
Write-Output
} else { Write-Host "Does not exist."}
I gather from your comment that $list is an array of order numbers.
Next, you want to check if there is a file in a folder having that name, correct?
Then I'd suggest you use Test-Path instead of Get-ChildItem:
$folderToSearch = '\\servername\sharename\folder'
foreach ($Order in $list) {
$fileToCheck = Join-Path -Path $folderToSearch -ChildPath ('{0}.pdf' -f $Order)
if (Test-Path -Path $fileToCheck -PathType Leaf) {
"File found: $fileToCheck"
}
else {
"File $fileToCheck does not exist"
}
}
I have a script that executes a stored procedure on a SQL Server which returns XML. I then have a function to to format the XML in powershell so it is readable. When i open the XML in Chrome i get this error:
This page contains the following errors:
error on line 149 at column 27: Encoding error
Below is a rendering of the page up to the first error.
I think I may need to encode it in UTF8 but I am unsure where to do it in my code. Any help to rectify the error or how to do the encoding is appreciated.
Here is the Powershell that I run to get the XML file:
function Format-XML {
[CmdletBinding()]
Param ([Parameter(ValueFromPipeline=$true,Mandatory=$true)][string]$xmlcontent)
$xmldoc = New-Object -TypeName System.Xml.XmlDocument
$xmldoc.LoadXml($xmlcontent)
$sw = New-Object System.IO.StringWriter
$writer = New-Object System.Xml.XmlTextwriter($sw)
$writer.Formatting = [System.XML.Formatting]::Indented
$xmldoc.WriteContentTo($writer)
$sw.ToString()
}
$Date = Get-Date -format "yyyyMMdd_HHmm"
$File = "C:\Temp\MyFile"+$Date+".xml"
$Query = "EXEC dbo.usp_MyProc"
$resultRow = Invoke-Sqlcmd -Query $Query -database MyDatabase -ServerInstance MyServer
Format-xml $resultRow['results'] | Set-Content -Path $File -Force
Comment "Try appending -Encoding UTF8 to your last line" from Martin Brandi worked
I am trying to log in to the the Oracle DB using PowerShell and run a script called "C:\Users\Administrator\Desktop\oracle\OracleCleanTest.sql", When I execute the PS nothing happens.
Here is what I have.
$adminLogon = "sys as sysdba/manager#ORCL"
$logon = "sqlplus\sql/manager#ORCL"
$mydata = Invoke-SqlPlus -inputfile "#C:\Users\Administrator\Desktop\oracle\OracleCleanTest.sql" $logon
I've also tried this.
$database = "ORCL";
$user = "sys as sysdba";
$pw = "manager";
sqlplus.exe -d $database -U $user -P $pw -I "#C:\Users\Administrator\Desktop\oracle\OracleCleanTest.sql"
I tried this.
& 'C:\app\Administrator\product\11.2.0\client_1\BIN\sqlplus.exe' 'QE-JDBC-1/manager#ORCL sys as sysdba' '#C:\Users\Administrator\Desktop\oracle\OracleCleanTest.sql'
I get the error, "& : The module 'sqlplus' could not be loaded. For more information, run 'Import-Module sqlplus'.
At line:5 char:3
+ & $mydata Invoke-SqlPlus -inputfile "#C:\Users\Administrator\Desktop\oracle\Orac ...
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (sqlplus\sql/manager#ORCL:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CouldNotAutoLoadModule"
I use the call operator, &, as Keith Hill has suggested with the question, How to run an EXE file in PowerShell with parameters with spaces and quotes.
& 'path\sqlplus.exe' 'system/password#dbase as sysdba'
I placed the username, password in quotes due to the spaces.
To start a script, I add another parameter as follows:
& 'path\sqlplus.exe' 'system/password#dbase as sysdba' '#my_script.sql'
If you are receiving the ORA-12154 error, and you know that other users have
established connections (which implies that the database listener is running
properly); I would then examine if SQL*Plus can find my tnsname file.
My first task would be to see if I can tnsping as follows in Windows cmd.exe:
tnsping orcl
It will confirm that a connection can (or can not be established).
If it cannot, I would check to see if the environment variable, ORACLE_HOME,
is set. SQL*Plus uses this to find tnsname.ora file.
If it is not set, I would execute this statement in PowerShell (to establish
this environment variable):
[Environment]::SetEnvironmentVariable("ORACLE_HOME", "C:\app\Administrator\product\11.2.0\client_1" , "User")
Next, I would retry to tnsping (identified above).
Once successful, I would re-try to execute the script running command above.
I use this:
$cmd = "cmd.exe"
$args = ("/c sqlplus {0}/{1}#{2}:{3}/{4} #{5} {6}" -f $userName, $password, $tnsAlias, $port, $dbInstance, $sqlScript, $outputFileName)
&$cmd $args
In your Windows PowerShell command prompt the code does not require variable setting or anything fancy. Just do this:
sqlplus ElBankoUser\SupaSecretyPass "#C:\Users\ElBankoUser\Documents\MaFancySckrp.sql"
You can use .NET Oracle library DLL, just make sure you have the required DLL file under the lib folder
Add-Type -Path "lib\Oracle.ManagedDataAccess.dll"
$query = "select 1 as Col1, 2 as Col2, 3 as Col3 from dual
union
select 4 as Col1, 5 as Col2, 6 as Col3 from dual
union
select 7 as Col1, 8 as Col2, 9 as Col3 from dual"
$cn = New-Object Oracle.ManagedDataAccess.Client.OracleConnection -ArgumentList "TNS-ConnectionString-Here"
$cmd = New-Object Oracle.ManagedDataAccess.Client.OracleCommand -ArgumentList $query
$cmd.Connection = $cn
try {
$cn.Open()
$reader = $cmd.ExecuteReader()
while ($reader.Read()) {
$col1 = $reader["Col1"]
$col2 = $reader["Col2"]
$col3 = $reader["Col3"]
Write-Host $col1, $col2, $col3
}
} catch {
Write-Error $_.Exception.Message
} finally {
$cmd.Dispose()
$cn.Dispose()
}
Why not use this?
sqlplus -s $adminLogin "#C:\Users\Administrator\Desktop\oracle\OracleCleanTest.sql"
-s just suppresses the sqlplus banner.
Hi all: This is what I'm trying to do....
Take a result set (eg. listoffailedcomputers.txt) and run a copy command on every item inside the result set.
The logic is to run a copy command on all the computers in that failedlistofcomputers.txt so that the end result will have that folder copied down locally on all computers on that list.
I can do this by using a remote console on all those computers but that would not be efficient.
Thank You.
Here is the code that I wrote so far.......
$failedcomputers = gc c:\listoffailedcomputers.txt
foreach ($failedcomputer in $failedcomputers)
{
$failedcomputer | copy-item \\server\patch\*.* -destination c:\patch\
}
And this is the error I'm getting......
Copy-Item : The input object cannot be bound to any parameters for the command
either because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.
At copypatchtofailedcomputers.ps
+ $failedcomputer | copy-item <<<< \\server\patch\ -destination c:\patch\
+ CategoryInfo : InvalidArgument: (mycomputername:PSObject) [Copy-
Item], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Command
s.CopyItemCommand
If I remove the pipe between the $failedcomputer variable and the copy-item command on my statement, I'll get a unexpected token error.
You can't just pipe a computername into any cmdlet and expect it to understand how to use it. Copy-Item doesn't even include a -ComputerName parameter. You could try two approaches
You could remote execute copy-item on each computer, like this:
$failedcomputers = gc c:\listoffailedcomputers.txt
foreach ($failedcomputer in $failedcomputers)
{
Invoke-Command -ComputerName $failedcomputer -ScriptBlock { copy-item \\server\patch\*.* -destination c:\patch\ }
}
Or, if you have file access to all remote computers from your computer, you could try to copy directly from one network share to another(the destination computer), like this:
$failedcomputers = gc c:\listoffailedcomputers.txt
foreach ($failedcomputer in $failedcomputers)
{
copy-item \\server\patch\*.* -destination "\\$failedcomputer\c$\patch\"
}
Another possibility:
$failedcomputers = gc c:\listoffailedcomputers.txt
$CmdParams =
#{
ClassName = 'Win32_Process'
MethodName = 'Create'
Arguments = #{ CommandLine = 'copy \\server\patch\*.* c:\patch\' }
}
Invoke-CimMethod #CmdParams -ComputerName $failedcomputers
That should multi-thread it, without the overhead of spinning up a bunch of remote PS instances just to do a file copy.
If you look at the Get-Help Copy-Item -full in ISE it tells you what it can accept on the pipeline. You can pipe a string that contains a path to Copy-ItemProperty. You are actually piping a hostname in this instance, which is why you are getting that error.
Try this:
copy-item \\server\patch\*.* -destination \\$failedcomputer\C$\patch