The following code throws an exception in Powershell V1 (Excel 2007):
$E = New-Object -COM "Excel.Application"
$E.Visible = $True
$wb = $E.Workbooks.Add() #<<<Exception here
The error says that the format might be old or that the type library is not valid (translated from Spanish). A similar script for Word works just fine.
Office interop assemblies seem to have this problem when the current culture is not en-US. The obvious workaround is to set the culture.
It's important to run the whole thing as a single command on the interactive console, since PowerShell V1 always creates a new thread for each command invocation.
PS C:\Users\jachymko> $e = new-object -com excel.application
PS C:\Users\jachymko> $e.workbooks.add()
Exception calling "Add" with "0" argument(s): "Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))"
At line:1 char:17
+ $e.workbooks.add <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
PS C:\Users\jachymko> & {
>> [threading.thread]::CurrentThread.CurrentCulture = 'en-US'
>> $e = new-object -com excel.application
>> $e.workbooks.add()
>> $e.visible=1
>> }
>>
Adapted to Powershell from one of the solutions proposed in MS Help and Support Article 320369.
$ci = new-object system.globalization.cultureinfo "en-US"
$e = New-Object -COM "Excel.Application"
$e.Visible = $True
$e.UserControl= $True
$books = $e.Workbooks
$books.PSBase.GetType().InvokeMember( `
"Add", `
[system.reflection.bindingflags]::InvokeMethod, `
$null, $books, $null, $ci)
From the same article:
When you use one of these workarounds for a computer where the regional settings
do not match the current language version of Office, you should be familiar with
how Excel behaves and how Excel will interpret data that might be formatted for
a specific locale.
I had this issue when trying to open a workbook. I added this line:
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
Related
I'm slowly teaching myself PowerShell and I'm completely baffled by enums. To my understanding, they're just a collection of friendly names for what are really integer values. Okay, ... that's great ... but how do you get PowerShell to actually "see" them?
Example:
[System.Windows.Forms.Application]::EnableVisualStyles();
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.Width = $img.Size.Width;
$form.Height = $img.Size.Height;
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Width = $img.Size.Width;
$pictureBox.Height = $img.Size.Height;
$pictureBox.SizeMode = PictureBoxSizeMode.StretchImage
This would be great if PowerShell had any clue what "PictrueBoxSizeMode.StretchImage" was.
It's a numeric value -- I know that -- you know that -- how do I get PowerShell to know that?
Thanks in advance?
Basic:
[System.Windows.Forms.PictureBoxSizeMode].GetEnumNames()
Advanced (names along with their numeric equivalents):
[System.Enum]::GetNames([System.Windows.Forms.PictureBoxSizeMode])|
ForEach-Object {"{0} {1}" -f
[System.Windows.Forms.PictureBoxSizeMode]::$_.value__, $_ }
Also compare Get-EnumValue function (custom cmdlet) in my answer to Getting enum values of Pseudo-Enum classes at Code Review.
Edit
All above code containing [System.Windows.Forms.PictureBoxSizeMode] run in powershell_ise. Unfortunately, powershell raises TypeNotFound error:
PS D:\PShell> [System.Windows.Forms.PictureBoxSizeMode]::StretchImage
Unable to find type [System.Windows.Forms.PictureBoxSizeMode]. Make sure that the assembly that contains this type is loaded. At line:1 char:1
+ [System.Windows.Forms.PictureBoxSizeMode]::StretchImage
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Windows.Forms.PictureBoxSizeMode:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
We need to renew a reference to System.Windows.Forms namespace; some sources advise renewing a reference to System.Drawing as well:
PS D:\PShell> [void] (Add-Type -AssemblyName System.Windows.Forms -PassThru)
PS D:\PShell> [void] (Add-Type -AssemblyName System.Drawing -PassThru)
PS D:\PShell> [System.Windows.Forms.PictureBoxSizeMode]::StretchImage
StretchImage
PS D:\PShell> [System.Windows.Forms.PictureBoxSizeMode]::StretchImage.value__
1
PS D:\PShell>
Error I'm getting from PowerShell:
Cannot convert argument "srv", with value: "[DBADEV\SQL2008r2]", for "SqlBackup" to type "Microsoft.SqlServer.Management.Smo.Server": "Cannot convert the "[DBADEV\SQL2008r2]" value of type
"Microsoft.SqlServer.Management.Smo.Server" to type "Microsoft.SqlServer.Management.Smo.Server"."
At line:23 char:1
+ $backup.SqlBackup($srv)
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
I'm attempting to write a PowerShell script to restore a database from our Production box and into our DBADEV box. Below is the code I'm using which is then producing the error.
#Clear Screen
cls
#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
$ErrorActionPreference = "Inquire"
# Restore [SQLSRV2k8-0102\SQL2008] instance
$BackupFile = Get-ChildItem "\\NetworkShare\r`$\MSSQL10.SQL2008\MSSQL\Backup\AdventureWorks2008r2" | select -Last 1
$BackupFile
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server("DBADEV\SQL2008r2")
$res = New-Object Microsoft.SqlServer.Management.Smo.Restore
$backup = New-Object Microsoft.SqlServer.Management.Smo.Backup
$Backup.Devices.AddDevice($BackupFile, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
$Backup.Database = "AdventureWorks2008r2"
$Backup.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database
$backup.Initialize = $true
$backup.SqlBackup($srv)
$srv.Databases["AdventureWorks2008r2"].Drop()
$res.Devices.AddDevice($BackupFile, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
$res.Database = "AdventureWorks2008r2"
$res.NoRecovery = $true
$res.SqlRestore($srv)
The error seems a bit cryptic to me (as do most PowerShell errors). Any thoughts on why this is occurring? I'm also getting the error when I use Mike Fal's powershell script here: http://www.mikefal.net/2014/07/22/restoreautomation-powershell-module/
The one thing that seems to get me past this error is by passing "DBADEV\SQL2008r2" directly into SQLRestore,
i.e. $res.SqlRestore("DBADEV\SQL2008r2") instead of $res.SqlRestore($srv)
This now generate an error stating "Restore failed for Server 'DBADEV\SQL2008r2'
Well from my experiences this kind of errors appear because of wrong name/data type in variable.
I would try to escape \ in "DBADEV\SQL2008r2"
or try what I found on MSDN
$srv = new-Object Microsoft.SqlServer.Management.Smo.Server("(local)")
Write-Host $srv.Information.Version
so it could look like
New-Object Microsoft.SqlServer.Management.Smo.Server("(DBADEV\SQL2008r2)")
I'm trying to use Powershell V2.0 to programatically compact and repair MS Access 2007 (.accdb) databases. The code I've created below works as part of the final code (several backup procedures occur prior to this function running).
I'm running into trouble though as all the databases are password protected and I need to run the script without the user having to enter the passwords manually. Here's my code so far:
Param([string]$strDBPath,[string]$strBUPath,[string]$strPwd)
$ErrorActionPreference = "Stop"
function CompactAndRepairDB {
regsvr32 "C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll"
regsvr32 "C:\Program Files\Microsoft Office\Office12\Acedao.dll"
regsvr32 "C:\WINNT\assembly\Microsoft.Office.Interop.Access.Dao\12.0.0.__71e9bce111e9429c\Microsoft.Office.Interop.Access.Dao.dll"
$Database = New-Object -ComObject Microsoft.Office.Interop.Access.Dao.DBEngine
$Database.CompactRepair($strDBPath,$strBUPath,"","",";pwd=" + $strPwd)
Remove-Item $strDBPath
Rename-Item $strBUPath $strDBPath
}
CompactAndRepairDB
The code throws an error though as below:
Cannot load COM type Microsoft.Office.Interop.Access.Dao.DBEngine.
At U:\Scripts\CompactRepairDatabase.ps1:11 char:27
+ $Database = New-Object <<<< -ComObject Microsoft.Office.Interop.Access.Dao.DBEngine
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotLoadComObjectType,Microsoft.PowerShell.Commands.NewObjectCommand
How do I load the correct library / COM object to complete the operation or is there an alternative method to achieve the .CompactRepair method using the password? Thanks
Remove the -ComObject from the line:
$Database = New-Object -ComObject Microsoft.Office.Interop.Access.Dao.DBEngine
Microsoft.Office.Interop.Access.Dao.DBEngine will be a managed interop wrapper around DAO.DBEngine so you don't need the -ComObject switch.
Try this:
Add-Type -AssemblyName Microsoft.Office.Interop.Access
$File = "Your.accdb"
$DbEng = new-object Microsoft.Office.Interop.Access.Dao.DBEngineClass # no square bracket []
$Db = $DbEng.OpenDatabase($File)
$Db
I have the following Powershell script I am trying to run:
add-type -path "C:\Program Files (x86)\Microsoft SQL Server\110\DAC\bin\Microsoft.SqlServer.Dac.dll";
$d = new-object Microsoft.SqlServer.Dac.DacServices "server=localhost"
# Load dacpac from file & deploy to database named pubsnew
$dp = [microsoft.sqlserver.dac.dacpackage]::load("c:\deploy\MyDbDacPac.dacpac")
$d.deploy($dp, "MyDb", $true)
However, when it runs, I am getting the following error:
New-Object : Exception calling ".ctor" with "1" argument(s): "The type initializer for 'Microsoft.SqlServer.Dac.DacServices' threw an exception."
At C:\Scripts\DeployDacPac.ps1:3 char:16
+ $d = new-object <<<< Microsoft.SqlServer.Dac.DacServices "server=localhost"
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : Cons tructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
I am trying to run this for an automated database deploy but cannot get past this weird error.
I have already set my execution policy to remotesigned and updated my runtime version for Powershell to .NET 4.0. Can't figure out what else could be wrong.
Any help would be greatly appreciated!
The problem here is that the default authentication method is SQL Server authentication which expects a username and password. You will need to either supply those parameters or explicitly specify that Windows authentication should be used. You can do this by replacing your connection string argument with the following.
"server=localhost;Integrated Security = True;"
Alternatively, you could use the following function to encapsulate this logic. Note that the default parameter set is 'WindowsAuthentication' which does not include the UserName or Password parameters. If you supply either of these, Powershell will use the 'SqlServerAuthentication' parameter set and the $PSCmdlet.ParameterSetName variable will be set appropriately.
function Get-DacServices()
{
[CmdletBinding(DefaultParameterSetName="WindowsAuthentication")]
Param(
[string]$ServerName = 'localhost',
[Parameter(ParameterSetName='SqlServerAuthentication')]
[string]$UserName,
[Parameter(ParameterSetName='SqlServerAuthentication')]
[string]$Password
)
$connectionString = "server=$serverName;";
if($PSCmdlet.ParameterSetName -eq 'SqlServerAuthentication')
{
$connectionString += "User ID=$databaseUsername;Password=$databasePassword;";
}
else
{
$connectionString += "Integrated Security = True;";
}
$result = new-object Microsoft.SqlServer.Dac.DacServices $connectionString;
return $result;
}
I'm logged in at domain "domain1" with my account. I wish via powershell to be able to update users in domain "domain2" via my supe ruser account "suaccount" with password "password1". Trust is established between the two.
Running PowerShell 2.0 and .NET 3.5 SP1
I have gotten this far:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$context = New-Object -TypeName
System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, "domain2", "OU=TestOU,DC=domain2", "suaccount", "password1"
$usr = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList $context
$usr.Name = "AM Test1"
$usr.DisplayName = "AM Test1"
$usr.GivenName = "AM"
$usr.SurName = "Test1"
$usr.SamAccountName = "AMTest1"
$usr.UserPrincipalName = "amtest1#mtest.test"
$usr.PasswordNotRequired = $false
$usr.SetPassword("errr")
$usr.Enabled = $true
$usr.Save()
Pretty new to PowerShell, any pointers? I want to edit/create users on the "other" domain so to speak.
I get the error:
"Exception calling "Save" with "0" argument(s): "General access denied error
"
At C:\Script\Sandbox\Morris PowerShell Application\includes\mo\mo.ps1:104 char:14
+ $usr.Save <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException"
Any pointers?
From comments: Try using for username this format domain2\username, and always use the FQDN for the domain. – Christian yesterday