PowerShell Unable to find type - powershell

I'm having trouble with an error when I try to run my PowerShell script from the command line:
Unable to find type [System.Windows.Forms.ListViewItem]
I have tried different ways to import the required classes:
using assembly System.Windows.Forms
using namespace System.Windows.Forms
using namespace System.Drawing
Add-Type System.Windows.Forms
In PowerShell ISE, I can run my script without any errors. But when I try to execute my script from CMD it doesn't work. It's exactly the same code and the same script files. This is the command I use to execute the script in CMD followed by the error messages:
C:\Users\Admin>powershell -File "C:\Folder\Main.ps1"
At C:\Folder\Main.ps1:35 char:30
+ ... return (([int](([System.Windows.Forms.ListViewItem]$a).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:35 char:114
+ ... umnIndex].Text)) - ([int](([System.Windows.Forms.ListViewItem]$b).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:37 char:41
+ ... return ([String]::Compare(([System.Windows.Forms.ListViewItem]$a).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:37 char:115
+ ... [$this.columnIndex].Text, ([System.Windows.Forms.ListViewItem]$b).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TypeNotFound
The error messages refer to the code below. This is my only class in that script:
class ListViewItemComparer : System.Collections.IComparer {
[int]$sortOrder
[String]$columnType
[int]$columnIndex
ListViewItemComparer() {
$this.sortOrder = 1
$this.columnType = "String"
$this.columnIndex = 0
}
ListViewItemComparer([int]$sortOrder, [String]$columnType, [int]$columnIndex) {
$this.sortOrder = $sortOrder
$this.columnType = $columnType
$this.columnIndex = $columnIndex
}
[void] ChangeSorting([int]$columnIndex, [String]$columnType) {
if($this.columnIndex -eq $columnIndex) {
$this.sortOrder *= -1
} else {
$this.columnIndex = $columnIndex
$this.sortOrder = 1
}
$this.columnType = $columnType
}
[int] Compare([Object]$a, [Object]$b) {
if($this.columnType -eq "Number") {
return (([int](([System.Windows.Forms.ListViewItem]$a).SubItems[$this.columnIndex].Text)) - ([int](([System.Windows.Forms.ListViewItem]$b).SubItems[$this.columnIndex].Text))) * $this.sortOrder
} else {
return ([String]::Compare(([System.Windows.Forms.ListViewItem]$a).SubItems[$this.columnIndex].Text, ([System.Windows.Forms.ListViewItem]$b).SubItems[$this.columnIndex].Text)) * $this.sortOrder
}
}
}
I'm using the type System.Windows.Forms.ListViewItem at other places too in my code, but there is no problem outside of a class. I don't even have to write the whole class path, just ``ListViewItem` works as well.
Can somebody tell me why the type System.Windows.Forms.ListViewItem is not recognized?
Why is it recognized outside the ListViewItemComparer class in the same script file?
Why does this error occur when I run the script from CMD and not in PowerShell ISE?

Related

How to check if custom culture exists

I have created one custom culture as 'gh-es'. I am trying to check if its already registered.its working fine if culture is registered but if not it throw an error in start only.
I am unable to find how to check if a culture is present or to check if its exists
$CustomCulture= [cultureinfo]::GetCultureInfo('gh-es')
If($CustomCulture -ne null)
{
Write-output "culture already registered"
}
Else
{
$CultureName = 'gh-es'
$BaseCulture=[cultureinfo]::GetCultureInfo('es-US')
$BaseRegion = New-Object System.Globalization.RegionInfo 'es-US'
try {
# Set up CultureAndRegionInfoBuilder
Add-Type -AssemblyName sysglobl
$CultureBuilder = New-Object System.Globalization.CultureAndRegionInfoBuilder
#($CultureName,[System.Globalization.CultureAndRegionModifiers]::None) $CultureBuilder.LoadDataFromCultureInfo($BaseCulture)
$CultureBuilder.LoadDataFromRegionInfo($BaseRegion)
$CultureBuilder.Register()
}
catch
{
throw
}
}
this is what i mean by using try/catch to handle an error when checking for a culture ...
try {
[cultureinfo]::GetCultureInfo('666-santa')
}
catch
{
'something glitched'
}
the output = something glitched
without the try/catch, the output is an error msg ...
Exception calling "GetCultureInfo" with "1" argument(s): "Culture is not supported.
Parameter name: name
666-santa is an invalid culture identifier."
At line:1 char:1
+ [cultureinfo]::GetCultureInfo('666-santa')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : CultureNotFoundException

Override Creation for Monitors and Rules

I want to create PowerShell scripts to override some parameter of my monitor and rule. I used the below code, but I have some errors. I want override my overidable parameter not enabled or something else. How can I doe this?
$mps = Get-SCOMManagementPack | ? {$_.Name -like "test"}
$overrideMp = Get-SCOMManagementPack -DisplayName "Overrides"
$overridename = "testmonitor.Overrides"
$monitor = 'testmonitor'
$override = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorPropertyOverride($overrideMp,$overridename)
$override.Monitor = $monitor
$override.Property = 'WarningThreshold'
$override.Value = 80
$override.DisplayName = "Overrides"
$overrideMp.Verify()
$overrideMp.AcceptChanges()
Errors:
error1: Exception setting "Property": "Cannot convert value "WarningThreshold" to
type "Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorProperty".
Error: "Unable to match the identifier name WarningThreshold to a valid enumerator
name. Specify one of the following enumerator names and try again: Enabled,
TraceEnabled, Algorithm, AlgorithmPercentage, DefaultState, GenerateAlert,
AutoResolve, AlertPriority, AlertOnState, AlertSeverity, AlertMessage,
AlertParameter1, AlertParameter2, AlertParameter3, AlertParameter4,
AlertParameter5, AlertParameter6, AlertParameter7, AlertParameter8,
AlertParameter9, AlertParameter10, MemberInMaintenance, MemberUnavailable,
IgnoreMemberInMaintenance, IgnoreMemberUnavailable""
At line:1 char:2
+ $override.Property = $parametername
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
error2 : Exception calling "AcceptChanges" with "0" argument(s): "Database error.
MPInfra_p_ManagementPackInstall failed with exception: Failed to validate item:
testrule1"
At line:193 char:1
+ $MP.AcceptChanges()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ManagementPackException
The error message looks rather clear to me. There is no property WarningThreshold in the ManagementPackMonitorProperty enumeration. I don't have much experience with SCOM, but you probably need to override the property AlertOnState for monitors where the property AlertSeverity has the value Warning.
Try something along the lines of this:
$mps | Get-SCOMMonitor | Where-Object {
# (other selection criteria) -and
$_.AlertSettings.AlertSeverity -eq 'Warning'
} | ForEach-Object {
$ctx = Get-SCOMClass -Id $_.Target.Id
# ...
$override = New-Object ...
$override.Monitor = $_
$override.Property = 'AlertOnState'
$override.Value = 80
$override.Context = $ctx
# ...
}
Code adopted from here (probably the same place where you found it). Not sure if this works, though. Like I said, I have very little experience with SCOM, and I don't have a SCOM server available for testing.
I'll try to debug it tomorrow in the office.
BTW, there is a third-party tool for override management called MPTuner: http://mpwiki.viacode.com/default.aspx?g=mptuner
It's free so you should try.
Roman.
It's quite confusing, but there are two different type of overrides for each workflow type. For a monitor there are:
MonitorPropertyOverride
MonitorConfigurationOverride
You are using the first one, wgich is for standard parameters only, like Enabled, for example. For any custom parameters use Configuration Override.

PowerShell and VB6 COM+ modules: Object variable or With block variable not set

I´m trying to use powershell to do automatic tests in my system, but 30% of this system is VB6 modules used thru COM. Some os these modules uses private variables that are globals inside the module. With VB6 functions that don´t use these variables, everything works fine, but with the functions that rely on these "private globals", I´m getting the error "Object variable or With block variable not set". Unfortunately, migrate this VB6 code will not occur in short term.
This is a piece of this legacy code:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 1 'NoTransaction
END
Attribute VB_Name = "Data"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
Option Explicit
Private oConn As ADODB.Connection
Private oRs As ADODB.Recordset
Public Function rsOperadora(ByVal sUser As String, _
ByVal sPassword As String, _
ByVal sIP As String, _
ByVal sSystem As String, _
ByVal sModule As String)
Dim sSql As String
sSql = "select * from operator"
Call Connect(sUser, sPassword, sSystem, sModule, sIP)
oRs.CursorType = adOpenStatic
oRs.CursorLocation = adUseClient
oRs.Open sSql, oConn, , adLockBatchOptimistic
oRs.ActiveConnection = Nothing
Set rsOperadora = oRs
Set oConn = Nothing
End Function
What I tried to do:
PS E:\aazevedo> $tsdb = New-Object -ComObject "TSDB.Data"
PS E:\aazevedo> $tsdb.rsOperadora
OverloadDefinitions
-------------------
Variant rsOperadora (string, string, string, string, string)
PS E:\aazevedo> $tsdb.rsOperadora("ADMIN","8482867D8B958F0E","","DESENV11","")
Exception calling "rsOperadora" with "5" argument(s): "Object variable or With block variable not set"
At line:1 char:1
+ $tsdb.rsOperadora("ADMIN","8482867D8B958F0E","","DESENV11","")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
PS E:\aazevedo> $oRs = New-Object -ComObject "ADODB.Recordset"
PS E:\aazevedo> $tsdb.rsOperadora("ADMIN","8482867D8B958F0E","","DESENV11","")
Exception calling "rsOperadora" with "5" argument(s): "Object variable or With block variable not set"
At line:1 char:1
+ $tsdb.rsOperadora("ADMIN","8482867D8B958F0E","","DESENV11","")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
PS E:\aazevedo> oRs = New-Object -ComObject "ADODB.Recordset"
oRs : The term 'oRs' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ oRs = New-Object -ComObject "ADODB.Recordset"
+ ~~~
+ CategoryInfo : ObjectNotFound: (oRs:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
In this example, the function Connect open a database connection using ADO, assigning to the variable oConn.
I think my problem is the variable oRs.
Inside ASP Classic this module works.
PS: sorry for my poor english.

How do I instantiate CorRuntimeHost from mscoree.tlb in PowerShell?

I want to enumerate all the AppDomains in the current process from PowerShell. The process happens to be Visual Studio, which is hosting StudioShell. To do that I need to instantiate CorRuntimHost, which is part of mscoree.tlb, so I can adapt this C# code..
I tried to get the proper name of CorRunTimeHost and pass it to New-Object -COMObject "objectName". Based on this forum posting, I searched the registry and I think the correct name is CLRMetaData.CorRuntimeHost. However, while New-Object -ComObject 'CLRMetaData.CorRuntimeHost' -Strict does return an object, it only exposes the methods intrinsic to a COM object.
Based on this stackoverflow question I tried [Activator]::CreateInstance(). However, the following two statements give me the same problem as New-Object, namely I can't call the ICorRuntimeHost::EnumDomains() method.
$corRuntimeHost = [Activator]::CreateInstance([Type]::GetTypeFromProgID('CLRMetaData.CorRuntimeHost'));
$enumerator = $null;
$corRuntimeHost.EnumDomains([ref]$enumerator);
Method invocation failed because [System.__ComObject] doesn't contain a method named 'EnumDomains'.
At line:1 char:1
+ $corRuntimeHost.EnumDomains([ref]$enumerator)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
To get it working in PowerShell 3.0 I ended up having to use an AssemblyBuilder. Below is the working code:
The problem seems to be that there is no public constructor for mscoree.CorRuntimeHostClass in .NET 4.0 but there is in 3.5.
I later tested this on a Windows 7 VM with powershell 2.0 and now this code will work in PowerShell 2.0 and 3.0.
$tlbName = Split-Path -Parent ([AppDomain]::CurrentDomain.GetAssemblies() | Where { $_.Location -Match '\\mscorlib.dll$' }).Location
$tlbName = Join-Path $tlbName 'mscoree.tlb';
$csharpString = #"
//adapted from here http://blog.semanticsworks.com/2008/04/enumerating-appdomains.html
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
public class ListProcessAppDomains
{
[DllImport( `"oleaut32.dll`", CharSet = CharSet.Unicode, PreserveSig = false )]
private static extern void LoadTypeLibEx
(String strTypeLibName, RegKind regKind,
[MarshalAs( UnmanagedType.Interface )] out Object typeLib);
private enum RegKind
{
Default = 0,
Register = 1,
None = 2
}
private class ConversionEventHandler : ITypeLibImporterNotifySink
{
public void ReportEvent( ImporterEventKind eventKind, int eventCode, string eventMsg )
{
Console.Error.WriteLine("Kind: {0} Code: {1} Message");
}
public Assembly ResolveRef( object typeLib )
{
string stackTrace = System.Environment.StackTrace;
Console.WriteLine("ResolveRef ({0})", typeLib);
Console.WriteLine(stackTrace);
return null;
}
}
public static AssemblyBuilder LoadMsCoreeDll( ref Object typeLib ) {
ConversionEventHandler eventHandler = new ConversionEventHandler();
string assemblyName = "PoshComWrapper.dll";
LoadTypeLibEx( #"$($tlbName)", RegKind.None, out typeLib );
TypeLibConverter typeLibConverter = new TypeLibConverter();
return typeLibConverter.ConvertTypeLibToAssembly( typeLib, assemblyName, 0, eventHandler, null, null, null, null );
}
}
"#
# So we can run this scipt multiple times
try { [ListProcessAppDomains] } catch { Add-Type -TypeDefinition $csharpString }
function Get-AppDomain {
$typeLib = $null;
$assemblyBuilder = [ListProcessAppDomains]::LoadMsCoreeDll([ref] $typeLib)
$corRuntimeHostClass = $assemblyBuilder.CreateInstance('PoshComWrapper.CorRuntimeHostClass')
$enumHandle = [IntPtr]::Zero
$corRuntimeHostClass.EnumDomains([ref] $enumHandle);
$appDomain = $null;
do
{
$corRuntimeHostClass.NextDomain($enumHandle, [ref] $appDomain);
if ($appDomain -ne $null -and $appDomain.GetType() -eq [AppDomain]) { $appDomain; }
} while ($appDomain -ne $null)
}
Get-AppDomain

Call to EnvDTE.TextSelection.FindPattern from PowerShell fails with type mismatch

I'm building a custom scaffolder to use with MvcScaffolding. Trying to automate adding code to the beginning of a method, I came up with the following code:
$codeElement = Get-ProjectType "MyType"
foreach ($member in $codeElement.Members)
{
if ($member.Name -eq "CreateMappings")
{
$editPoint = $member.StartPoint.CreateEditPoint()
# here's where it's crashing
$editPoint.FindPattern("\{")
$editPoint.Insert("text")
}
}
When I run my custom scaffolder, FindPattern fails with
Exception calling "FindPattern" with "1" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
At Path\File.ps1:62 char:26
+ $editPoint.FindPattern <<<< ("\{")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
As opposed to this macro, which runs just fine:
Sub macro()
Dim objTD As TextDocument = DTE.ActiveDocument.Object("TextDocument")
Dim editPoint As EditPoint = objTD.StartPoint.CreateEditPoint()
If (editPoint.FindPattern("\{", vsFindOptions.vsFindOptionsRegularExpression)) Then
editPoint.CharRight()
editPoint.Insert("text")
End If
End Sub
What am I doing wrong?