WINWORD Error when run in Task Scheduler "ExportAsFixedFormat" - powershell

I have a PowerShell script that leverages MS Word to convert txt files to .pdf. When executing the script in the PowerShell window there is no problem - the script works fine and does what it is suppose to do. However when executing this script from within the Task Scheduler MS Word fails when exporting the document as .pdf. To be clear, the script is executing as a Scheduled Task, I know this because I am sending all the script output to a transcript file. In the transcript file I see the following error right at this line:
$doc.ExportAsFixedFormat( $outputFullPath , $wdExportFormatPDF )
This is the error.
PS>TerminatingError(Convert-Txt2Pdf): "Exception calling "ExportAsFixedFormat" with "2" argument(s): "Word has encountered a problem.""
Error Caught
Convert-Txt2Pdf : Exception calling "ExportAsFixedFormat" with "2" argument(s): "Word has encountered a problem."
At C:\Source\PowerShell\RunScripts\Run-Txt2Pdf2SP.ps1:55 char:9
+ Convert-Txt2Pdf `
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Convert-Txt2Pdf], MethodInvocationException
+ FullyQualifiedErrorId : COMException,Convert-Txt2Pdf
Inner Exception
at Microsoft.Office.Interop.Word.DocumentClass.ExportAsFixedFormat(String OutputFileName, WdExportFormat ExportForma
t, Boolean OpenAfterExport, WdExportOptimizeFor OptimizeFor, WdExportRange Range, Int32 From, Int32 To, WdExportItem It
em, Boolean IncludeDocProps, Boolean KeepIRM, WdExportCreateBookmarks CreateBookmarks, Boolean DocStructureTags, Boolea
n BitmapMissingFonts, Boolean UseISO19005_1, Object& FixedFormatExtClassPtr)
at CallSite.Target(Closure , CallSite , Object , Object , Object )
I have found nothing in the Event Viewer and have no idea what the problem is. What could be causing this error?
Thanks

Related

A positional parameter cannot be found that accepts argument '+' error using SqlClient in Powershell

I am getting an error in my powershell script for a runbook on Azure:
Write-Error : A positional parameter cannot be found that accepts argument '+'.
At Test-Update-IndexesForallShardsFromShardManagerRunbook:61 char:61
+
+ CategoryInfo : InvalidArgument: (:) [Write-Error], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteErrorCommand
Based on the logs I see on my Azure autmation account from a job that ran, I pinpointed the origin of the error in my script somewhere in the following code:
$updateStatisticSql = "UPDATE STATISTICS [$Using:tableName] ( [$Using:statName] );"
$CmdUpdateStats=new-object system.Data.SqlClient.SqlCommand($updateStatisticSql, $Conn1)
$CmdUpdateStats.CommandTimeout=1500
Try
{
$Ds=New-Object system.Data.DataSet
$Da=New-Object system.Data.SqlClient.SqlDataAdapter($CmdUpdateStats)
[void]$Da.fill($Ds)
}
Catch
{
# Will catch the exception here so other statistics can be processed.
Write-Error "Statistic " + $tableName + "(" + $statName + ") could not be updated. Investigate the statistic."
}
It seems after adding logging after each line, that it doesn't log after the "fill" function, so I assume something is going wrong there. But I am not seeing the relation between the error and this function. It also doesn't seem a script breaking error, since it never goes into the catch and the rest of the scripts runs fine. I also validated that the statistics are updated, even though the error I am getting.
So the error you are seeing is because you are trying to build a string using concatenation which means you have spaces and spaces are used to delimit parameters when calling cmdlets. Put all the concatenation into parens:
Write-Error ("Statistic " + $tableName + "(" + $statName + ") could not be updated. Investigate the statistic.")

How do I throw an exception showing the calling line?

When I purposely throw an exception the stack trace shows the code that decided to throw the exception.
Example error message!!
At C:\path\to\script.ps1:101 char:37
+ else { throw $message; }
+ ~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Example error message!!:String) [], RuntimeException
+ FullyQualifiedErrorId : Example error message!!
Is there a way in PowerShell that I can have it show the line that called my code. Because it is a problem with the calling code, not the throw line.

How Do I Catch by FullyQualifiedErrorId in PowerShell?

I have a script that creates new AD Objects (via New-ADObject, as it happens). If the object already exists, I need to catch and handle that. However, the exception type isn't nearly as explicit as the FullyQualifiedErrorId. Observe the below:
> $Error[-1] | Format-List -Property * -Force
writeErrorStream : True
PSMessageDetails :
Exception : Microsoft.ActiveDirectory.Management.ADException: An attempt was made to add an object to the directory with
a name that is already in use ---> System.ServiceModel.FaultException: The supplied entry already exists.
--- End of inner exception stack trace ---
at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowExceptionForExtendedError(String
extendedErrorMessage, Exception innerException)
at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowExceptionForFaultDetail(FaultDetail
faultDetail, FaultException faultException)
at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowException(AdwsFault adwsFault, FaultException
faultException)
at Microsoft.ActiveDirectory.Management.AdwsConnection.Create(ADAddRequest request)
at Microsoft.ActiveDirectory.Management.ADWebServiceStoreAccess.Microsoft.ActiveDirectory.Management.IADSy
ncOperations.Add(ADSessionHandle handle, ADAddRequest request)
at Microsoft.ActiveDirectory.Management.ADActiveObject.Create()
at Microsoft.ActiveDirectory.Management.Commands.ADNewCmdletBase`3.ProcessRecordOverride()
at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase.ProcessRecord()
TargetObject : ou=Domain Controllers,DC=cryotest,DC=testdom
CategoryInfo : NotSpecified: (ou=Domain Contr...test,DC=afcdom1:String) [New-ADObject], ADException
FullyQualifiedErrorId : An attempt was made to add an object to the directory with a name that is already in
use,Microsoft.ActiveDirectory.Management.Commands.NewADObject
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at Import-ADObjectOfClass, C:\Users\administrator\Desktop\Import-ADObjects.ps1: line 103
at <ScriptBlock>, C:\Users\administrator\Desktop\Import-ADObjects.ps1: line 137
at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {1, 1}
How can I make use of the more verbose information here in my Catch block?
The FullyQualifiedErrorId is just the the .Message property of the exception object along with the the fully-qualified name of the class where the exception originated.
You can't catch by FullyQualifiedErrorId, but you can catch by exception type:
try {
# Do something that causes the 'name already in use' exception you're getting.
} catch [System.ActiveDirectory.Management.ADException] {
if ($_.Exception.Message -ilike "*already in use") {
# Do something to handle the error condition.
}
}
Note that this won't be a portable solution across different languages, since the exception message may be localized on non-English builds of Windows.
In addition, you may have to modify your try block to include -ErrorAction Stop to ensure the error is caught.
If the error thrown by New-ADObject is not a terminating error using catch will not help. One thing you can do is use the ErrorAction parameter to make the error a terminating error:
try{
New-ADObject ... -ErrorAction Stop
}
catch{
... handle the error ....
}
I don't know if you can catch the exceptions by the FullyQualifiedErrorId, but I found this way to get it and it works for me:
$InerrMessage= $_.FullyQualifiedErrorId

Multiple parameter in powershell

I have a powershell script to call the SP which is shown below
$sqlTableConnection = New-Object [System.Data.SqlClient.SqlConnection]("Server=1xx.xx.xxx; Database=dbName; Integrated Security= True");
$sqlTableCmd = New-Object [System.Data.SqlClient.SqlCommand]
$sqlTableCmd.CommandText = "[System_Control].[usp_Check_system]"
$sqlTableCmd.Connection = $sqlTableConnection;
$jobName1 = "MASTER_JOB";
$sqlTableCmd.Parameters.AddWithValue("#JobName", $jobName1) ;
$outParameter = new-object System.Data.SqlClient.SqlParameter;
$outParameter.ParameterName = "#JobSatatus";
$outParameter.Direction = [System.Data.ParameterDirection]'Output';
$outParameter.DbType = [System.Data.DbType]'Boolean';
$sqlTableCmd.Parameters.Add($outParameter) ;
$sqlTableCmd.Connection = $sqlTableConnection
$sqlTableConnection.Open();
$sqlTableCmd.ExecuteNonQuery();
$truth = $sqlTableCmd.Parameters["#JobSatatus"].Value;
$sqlTableConnection.Close();
$truth;
but when I am running this I am getting below error
Exception calling "ExecuteNonQuery" with "0" argument(s): "The variable name '#
JobName' has already been declared. Variable names must be unique within a quer
y batch or stored procedure."
At line:15 char:33
+ $sqlTableCmd.ExecuteNonQuery <<<< ();
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Where I am doing mistake?
You should only be getting that error if you aren't re-initializing the SqlCommand object and so it has #JobName already defined.
I suspect you are getting this when you run it manually, not when you execute the script as a whole..
OR, if you are seeing it all the time, then maybe you moved this code into a function but the original $sqlTableCmd was initialized in the main code and now when this executes, it is in a different scope, but is getting confused by the one that was defined in the higher scope?
As I understand it, this line here is the one that should be setting things up fresh for you:
$sqlTableCmd = New-Object [System.Data.SqlClient.SqlCommand]

Call Windows Runtime Classes from PowerShell

Is there a way to call Windows Runtime (WinRT) classes (or objects) from a PowerShell script? I know that you can call COM objects, which WinRT classes are supposed to be "exposed" as ... but so far my attempts have failed...
This is my code I'm trying:
$lockscreen = New-Object -comObject Windows.System.UserProfile.LockScreen
Which gives me the following error:
New-Object : Retrieving the COM class factory for component with CLSID {00000000-0000-0000-0000-000000000000} failed
due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
Does anyone know the correct "COM Class" that I should be using for WinRT classes?
just reference the type, to "load" the assembly...
[Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,ContentType=WindowsRuntime]
[Windows.System.UserProfile.LockScreen]::OriginalImageFile
if you don't want the type to be returned in your powershell results then
$null = [Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,ContentType=WindowsRuntime]
Here is something hacky that seems to work:
PS> new-object "Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,ContentType=WindowsRuntime"
new-object : Constructor not found. Cannot find an appropriate constructor for type
Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,ContentType=WindowsRuntime.
At line:1 char:1
+ new-object "Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,Con ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand
PS> [Windows.System.UserProfile.LockScreen]::OriginalImageFile
AbsolutePath : C:/Windows/Web/Screen/img100.png
AbsoluteUri : file:///C:/Windows/Web/Screen/img100.png
LocalPath : C:\Windows\Web\Screen\img100.png
Authority :
HostNameType : Basic
IsDefaultPort : True
IsFile : True
IsLoopback : True
PathAndQuery : C:/Windows/Web/Screen/img100.png
...
Note that the first call fails because LockScreen has no constructor but that call does something to pull in the WinRT projection/metadata such that you can now call the static methods/properties on the LockScreen class.
DISCLAIMER: there isn't any documentation that I can find on this New-Object syntax so it is entirely possible that Microsoft could change it considering it is essentially a "hidden" and probably not fully developed feature.