Learn about Windows PowerShell
Summary: The Scripting Guys answer questions about Windows Features, and discuss troubleshooting VBScript scripts and Windows PowerShell.
In this post:
Converting a VBScript Script to a Windows PowerShell Script
Hey, Scripting Guy! I need to convert one VBScript script to Windows PowerShell. Mostly, it is very easy, but one fragment I cannot reproduce in any way. In this part of the script, I need to create a new WMI class. It might be it is singleton. Whatever it is, I will need to populate its properties. Any Internet searches return only instance creation for existing classes, but that is not what I need. I need to create the entire class. Here is the VBScript code:
Sub PrepareWMI Dim WMI, wmiObject, wmiCol, wmiItem Set WMI = GetObject("winmgmts://./root/CIMv2") On Error Resume Next Set wmiObject = WMI.Get("PS_Class") If Err then Set wmiObject = WMI.Get wmiObject.Path_.Class = "PS_Class" wmiObject.Properties_.Add "TestProp", 123 'CIM_UINT32 wmiObject.Properties_.Add "Name", 8 'CIM_STRING wmiObject.Properties_("Name").Qualifiers_.Add "key", True wmiObject.Put_ End If On Error Goto 0 Set wmiCol = WMI.ExecQuery("SELECT * FROM PS_Class") For each wmiItem in wmiCol wmiItem.Delete_ Next End Sub
Follow-up: I found a workaround for current task—just creating a subclass of another WMI class, but this is different. This way I get a bunch of unneeded and properties. In VBScript when I create a new class from scratch, by default it contains no properties.
Here is my workaround:
$MSE = [wmiclass]"CIM_ManagedSystemElement" $PSClass = $MSE.PSBase.Derive("PS_Class") $PSClass.properties.add("TestProp",123) $PSClass.properties["Name"].Qualifiers.add("Key",$True) $PSClass.put() $Inst = $PSClass.psbase.CreateInstance() $Inst.TestProp = 12345 $Inst.Name = "First instance" $Inst.put()
-- VG
Hello VG,
That is essentially what I was going to do; you beat me to it. The “unwanted” properties you are getting are system properties that flow through on all WMI classes in Windows PowerShell. You are also getting properties that are inherited from CIM_ManagedSystemElement WMI abstract class from where you derive your new PS_Class WMI class.
All WMI classes in Windows PowerShell have the system properties that are shown here.
__GENUS : 2 __CLASS : PS_Class __SUPERCLASS : CIM_ManagedSystemElement __DYNASTY : CIM_ManagedSystemElement __RELPATH : PS_Class.Name="First instance" __PROPERTY_COUNT : 6 __DERIVATION : {CIM_ManagedSystemElement} __SERVER : MrEd1 __NAMESPACE : ROOT\cimv2 __PATH : \\MrEd1\ROOT\cimv2:PS_Class.Name="First instance"
The properties that are listed here are inherited.
Caption : Description : InstallDate : Status :
The properties seen here are the two properties you created in your script.
Name : First instance TestProp : 12345
Therefore, what you have is not really a “work around” but it is the way that it would be done. The way you can control what is output by default from your WMI class is to modify the format.xml file that is used by Windows PowerShell for your specific WMI class. In this way, using Get-WmiObject on it would only return your specific properties. This is done with win32_bios and other WMI classes. This is shown here:
PS C:\> gwmi win32_bios SMBIOSBIOSVersion : 7LETB7WW (2.17 ) Manufacturer : LENOVO Name : Ver 1.00PARTTBLx SerialNumber : L3L4518 Version : LENOVO - 2170
All the system properties and inherited properties are there, but they are hidden by default. By piping the output to the Format-List cmdlet, you can see everything:
PS C:\> gwmi win32_bios | fl * Status : OK Name : Ver 1.00PARTTBLx Caption : Ver 1.00PARTTBLx SMBIOSPresent : True __GENUS : 2 __CLASS : Win32_BIOS __SUPERCLASS : CIM_BIOSElement __DYNASTY : CIM_ManagedSystemElement __RELPATH : Win32_BIOS.Name="Ver 1.00PARTTBLx",SoftwareElementID="Ver 1.00PARTTBLx",Sof twareElementState=3,TargetOperatingSystem=0,Version="LENOVO - 2170" __PROPERTY_COUNT : 27 __DERIVATION : {CIM_BIOSElement, CIM_SoftwareElement, CIM_LogicalElement, CIM_ManagedSyste mElement} __SERVER : MrEd1 __NAMESPACE : root\cimv2 __PATH : \\MrEd1\root\cimv2:Win32_BIOS.Name="Ver 1.00PARTTBLx",SoftwareElementID=" Ver 1.00PARTTBLx",SoftwareElementState=3,TargetOperatingSystem=0,Version="L ENOVO - 2170" BiosCharacteristics : {7, 8, 9, 11...} BIOSVersion : {LENOVO - 2170, Ver 1.00PARTTBLx} BuildNumber : CodeSet : CurrentLanguage : enUS Description : Ver 1.00PARTTBLx IdentificationCode : InstallableLanguages : 1 InstallDate : LanguageEdition : ListOfLanguages : {enUS} Manufacturer : LENOVO OtherTargetOS : PrimaryBIOS : True ReleaseDate : 20080425000000.000000+000 SerialNumber : L3L4518 SMBIOSBIOSVersion : 7LETB7WW (2.17 ) SMBIOSMajorVersion : 2 SMBIOSMinorVersion : 4 SoftwareElementID : Ver 1.00PARTTBLx SoftwareElementState : 3 TargetOperatingSystem : 0 Version : LENOVO - 2170 Scope : System.Management.ManagementScope Path : \\MrEd1\root\cimv2:Win32_BIOS.Name="Ver 1.00PARTTBLx",SoftwareElementID=" Ver 1.00PARTTBLx",SoftwareElementState=3,TargetOperatingSystem=0,Version="L ENOVO - 2170" Options : System.Management.ObjectGetOptions ClassPath : \\MrEd1\root\cimv2:Win32_BIOS Properties : {BiosCharacteristics, BIOSVersion, BuildNumber, Caption...} SystemProperties : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...} Qualifiers : {dynamic, Locale, provider, UUID} Site : Container :
Using the Add-Windowsfeature Cmdlet to Add the Windows PowerShell ISE to a Remote Server
Hey, Scripting Guy! Is there way to use the Add-Windowsfeature cmdlet to add the Windows PowerShell ISE to a remote server that does not currently have it installed?
-- FR
Hello FR,
But of course. This is one of the awesome things about Windows PowerShell remoting. The Add-WindowsFeature cmdlet is available from the servermanager module. I talked about the servermanager module back in July during Group Policy Week. However, that module is not installed on a Windows 7 machine, even when the RSAT tools are installed. One reason for this is that the Add-WindowsFeature cmdlet “does not remote” because it does not have a –computername parameter. However, using Windows PowerShell remoting, you do not need to have the servermanager module installed on your Windows 7 machine, and you do not need to be able to remote Add-WindowsFeature because the commands will execute on the remote machine. The first thing to do is to use the Enter-PSSession cmdlet to enter a remote Windows PowerShell session on the target server that does not have Windows PowerShell ISE installed on it. After you have entered the remote Windows PowerShell session, import the servermanager module and check on the status of the Windows PowerShell ISE feature. These commands are shown here:
PS C:\> Enter-PSSession -ComputerName hyperv-box [hyperv-box]: PS C:\Users\ed\Documents> Import-Module *server* [hyperv-box]: PS C:\Users\ed\Documents> Get-WindowsFeature -Name *ise* Display Name ------------ ---- [ ] Windows PowerShell Integrated Scripting Environm... PowerShell-ISE
Note that the [ ] box is not checked in the above output. This means the Windows PowerShell ISE is not installed on the remote server.
Because I could use wildcard characters to get the Windows Feature, I decided to try to use a wildcard character to add the Windows Feature. This, however, results in the error shown here:
[hyperv-box]: PS C:\Users\ed\Documents> Add-WindowsFeature -Name *ise* Add-WindowsFeature : ArgumentNotValid: Invalid role, role service, or feature: '*ise *'. The name was not found. + CategoryInfo : InvalidData: (:) [Add-WindowsFeature], Exception + FullyQualifiedErrorId : NameDoesNotExist,Microsoft.Windows.ServerManager.Comm ands.AddWindowsFeatureCommand Success Restart Needed Exit Code Feature Result ---------- ------------- --------- -------------- False No Invali... {}
When I use the correct name, however, the command comes off without a hitch. The output from Add-WindowsFeature indicates if I need to restart the server or not. If I do, I could use the Restart-Computer cmdlet. When I am done, I use the Exit-PSSession command to exit the remote Windows PowerShell session. These two commands are shown here:
[hyperv-box]: PS C:\Users\ed\Documents> Add-WindowsFeature -Name PowerShell-ISE Success Restart Needed Exit Code Feature Result ---------- -------------- --------- -------------- True No Success {Windows PowerShell Integrated Scripting E... [hyperv-box]: PS C:\Users\ed\Documents> Exit-PSSession PS C:\>
The following image illustrates using all these commands in a Windows PowerShell session from my Windows 7 desktop to the remote Windows Server 2008 R2 server named hyperv-box.
Troubleshooting a VBScript Script to Find and Replace in SQL Server 2008
Hey, Scripting Guy! I am trying to do a find and replace for a SQL 2008 CreateTables.sql file that I receive from one vendor that I need to run in a SQL 2005 environment as part of a nightly BCP. The problem is that the datatype [date] is not recognized in SQL 2005, so I'd like to search through the 4000+ lines of the CreateTables.sql file and replace [date] with [datetime] through a script. I have written the VBscript script below; however, when I run the script I wrote, it inserts carriage returns and spaces which render the SQL file useless. Is there a way I can do this through a Windows PowerShell script or other script?
Const ForReading = 1 Const ForWriting = 2 Set objFSO = CreateObject("scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("C:\Scripts\CreateTables.sql", ForReading) strText = objFile.ReadAll objFile.Close strNewText = Replace(strText, "[date]", "[datetime]") Set objFile = objFSO.OpenTextFile("C:\Scripts\CreateTables.sql", ForWriting) objFile.WriteLine strNewText objFile.Close
--JD
Hello JD,
I would use write instead of writeline. The code to modify is shown here:
Set objFile = objFSO.OpenTextFile("C:\Scripts\CreateTables.sql", ForWriting) objFile.Write strNewText objFile.Close
Writeline includes vbcrlf (carriage return line feed), and write does not.
You could, of course, write the script in Windows PowerShell, but there is no need to do so when you have a perfectly acceptable VBScript script
Well, this concludes another edition of Quick-Hits Friday. Join us tomorrow for the Weekend Scripter as we delve into the mysteries of the Windows PowerShell ISE.
We would love for you to follow us on Twitter and Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
You can't do Find and Replace on the .sql file in a text editor?