Learn about Windows PowerShell
How Can I Migrate AutoText When I Upgrade from One Version of Microsoft Office to Another?
Hey, Scripting Guy! We are in the process of converting from Office 2003 to Office 2007. Many people use AutoText and I am trying to automate the process of converting or bringing over their AutoText. I created the below VBScript script, but am unable to open the file afterwards. Note: The sleep really did not change anything, but I was willing to try anything. In addition, if I do this process manually, it works just fine.
Set objWord=CreateObject("Word.Application")Set objDoc=objWord.Documents.Open("c:\Normal11.dot")WScript.Sleep 10000objDoc.SaveAs("c:\AutoText.dotx")objWord.Quit
Thank you for your time.
-- JS
Hello JS,
Your problem is you are trying to convert the file type—without actually converting it. Just changing the file extension does not work. When you do it manually through the GUI, it calls the appropriate method on the back end. Here is the documentation for the SaveAs method. There is an additional parameter you will need to use to convert the document to the .docx file format.
To convert to another format, you need to specify the appropriate value for the SaveFormat property. The additional format options are WdSaveFormat enumeration values.
Which Scripting Language Should I Start with When Getting into Scripting?
Hey, Scripting Guy! In my current role, I am finding that I have to compare Active Directory and Office Excel data on a regular basis. I think it is time to learn scripting to ease my workload and also to keep me from harassing other people for hastily written scripts. Some of the tasks I have to do are the following:
· Compare columns of information in Excel
· Compare members of an AD group
· Find machines in AD that appear in group X, Y, and Z
I am really wondering what the best language is to start with. Speaking to various people at work, they will generally lean toward whatever language they are best at rather than what language is best to actually learn. Therefore, it would be good to get some guidance here!
-- PD
Hello PD,
If I were going to spend time learning a new scripting language, I would learn Windows PowerShell. The reason is that it is the up-and-coming scripting language. VBScript is in maintenance mode and has had no new development work done on it since Windows XP shipped on October 25, 2001. There have been bug fixes, and security fixes, but no new features. Windows PowerShell, on the other hand, is undergoing active development—and Windows PowerShell 2.0 will introduce some amazing new features that will greatly simplify network administration. Windows PowerShell 2.0 is built into Windows Server 2008 R2 and Windows 7. It therefore forms the basis for many new management tools moving forward, such as Active Directory Users and Computers. Using the Active Directory cmdlets, much of the work you have been doing would be relatively simple.
Even using Windows PowerShell 1.0, the process of searching Active Directory is easier than it is with VBScript. For example, see the searching AD scripts using Windows PowerShell in the Script Center Script Repository.
For working with Excel, however, there is not a significant difference. Here is a series of Hey, Scripting Guy! articles I wrote that use Windows PowerShell. For learning Windows PowerShell, I would recommend the Microsoft Press book, Microsoft Windows PowerShell Step By Step. It was written by this really cool guy named Ed Wilson. J
If you want to learn VBScript, you may want to begin with the Scripting Guide. A good book on VBScript is the Microsoft Press book, Microsoft VBScript Step by Step.
A Question of Scripting Style
Hey, Scripting Guy! I have a question about scripts in the Script Repository. Why do none of the scripts end with WScript.Quit? In addition, why do you use WScript.Echo for each line, instead of WScript.Echo on the first line and carriage returns (& vbCr & _) on all the rest?
-- MB
Hello MB,
Those are all a matter of style. The use of Wscript.echo on each line makes the code easier to read for people who are just learning VBScript. The fact that you ask the question obviously means that you are more experienced. Feel free to make the change if you wish. I never use WScript.Quit. When the script ends, it quits, so from a “double-click” standpoint, there is no advantage of using it.
Can I Query for USB Mass Storage History?
Hey, Scripting Guy! I am not sure which one is better, but is it possible to query either the registry or Device Manager for USB mass storage history? I would like to be able query all the computers on my network for their use. I mostly just want to see the DeviceID of all mass storage devices. If possible, I would love to be able to create some type of insertion query to check a mass storage device and to compare its DeviceID to one that is allowed for use. If it does not match, I would like it to alert me somehow or disable the drive. I am not sure if all that is possible or not, but I will take the original query if the other stuff cannot be done.
-- CJ
Hello CJ,
There is no way to query this information via Device Manager (that I know of). This Get-UsbDeviceInfo.ps1 script retrieves USB storage information from the registry of a Windows 7 computer using Windows PowerShell.
Get-UsbDeviceInfo.ps1
Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR | ForEach-Object { Get-ChildItem -Path ($_.name -replace "HKEY_LOCAL_MACHINE", "HKLM:") | ForEach-Object { Get-ItemProperty -Path ($_.name -replace "HKEY_LOCAL_MACHINE", "HKLM:") }}
Where Can I Find Definitions of ADSI Classes?
Hey, Scripting Guy! I would like to ask if there is a place available where I can find the definitions of the different classes used by ADSI, such as wbemtest.exe in WMI. Thank you for your time.
--MA
Hello MA,
There are two tools you can use: the Schema Admin Tool and AdsiEdit. These two tools are part of the admin tool kit. To use the Schema Admin Tool, you must first register the schmmgmt.dll by using Regsvr32. Then you add it to an MMC snap-in. This is discussed in part in a recent Hey, Scripting Guy! Article: How Do I Search Active Directory?
Our Active Directory hub has many good articles, as well as links to the ADSI documentation on MSDN and to Active Directory documentation on TechNet.
How Can I Detect for Updates and Install Them Without Rebooting the Computer?
Hey, Scripting Guy! I chatted with you at Tech∙Ed 2009 in Los Angeles about a script that will detect if the monthly Microsoft security patches have been downloaded to a PC but have not been installed. The script would detect this situation and install the patches silently without rebooting the system.
I found a script on the Web, but it does not work. On a test system, I receive the “Updates are waiting to be installed” notification and I run this script. The script reports back that there are no patches waiting.
I guess what I am actually asking for is a means to duplicate the Windows shutdown/restart feature to “Install updates and shut down” without shutting down the system. (There are too many systems that cannot be forced to shut down in my situation.)
I would appreciate any help you can give me to help keep my users secure and let me sleep at night!
--CC
Hello CC,
I looked at your script, and do not see anything glaringly wrong with it. However, I also do not see where it downloads and installs updates either. That means the script really does not work as advertised! I am including below the SearchDownloadInstallWindowsUpdate.vbs script that I wrote for the first edition of the Windows Vista Resource Kit. It does exactly what you are interested in doing: It searches for software updates, downloads them, and then installs them. It does not reboot the computer, however.
One big thing I should advise you about: When you download and install updates from Windows Update, you should go ahead and reboot the computer. This is because the updates need to replace files that are in memory. What happens is that the version of the file on the hard disk drive is replaced, but the copy of the file that is in use—and is in memory—remains in memory. This means you have version 1 of the file in memory, and version 2 of the file on the hard disk drive. This leaves the computer in an unstable state. Additionally, if the update is a security update that fixes a vulnerability in the file, the patched version of the file is on the hard disk drive, but the vulnerable version of the file remains in memory. This means your computer is vulnerable to an outside attack using an exploit that was designed for the vulnerability you just patched. It is vital that you reboot immediately when patching security vulnerabilities in order to remain protected from attacks.
SearchDownloadInstallWindowsUpdate.vbs
'=========================================================================='' VBScript: AUTHOR: ed wilson , mred, 10/8/2006'' NAME: <searchDOwnloadInstallWindowsUpdate.vbs>'' COMMENT: Key concepts are listed below:'1. Microsoft Update object'2. Vista resource kit'==========================================================================Option ExplicitDim objSession 'update session objectDim objSearcher 'update searcher objectDim objResult 'search result objectDim objUpdate 'update objectDim objColUpdates 'updates collection objectDim objInstaller 'installer objectDim objDownloader'downloader objectDim strInstall 'rtn from command line argumentDim errRTN 'rtn code from installDim colNamedArguments 'WshNamed objectDim I 'countersubCheckCscript 'check to see if running in cscriptSet colNamedArguments = WScript.Arguments.NamedstrInstall = colNamedArguments("i") subCheckArgumentsWScript.Echo "Searching for updates..."Set objSession = CreateObject("Microsoft.Update.Session")Set objSearcher = objSession.CreateupdateSearcher()Set objResult = objSearcher.Search("IsInstalled=0 and Type='Software'")WScript.Echo "List of applicable items on the machine:"For I = 0 To objResult.Updates.Count-1 Set objUpdate = objResult.Updates.Item(I) WScript.Echo I + 1 & "> " & objUpdate.TitleNextIf objResult.Updates.Count = 0 Then WScript.Echo "There are no applicable updates." WScript.QuitEnd IfWScript.Echo vbCRLF & "Creating collection of updates to download:"Set objColUpdates = CreateObject("Microsoft.Update.UpdateColl")For I = 0 to objResult.Updates.Count-1 Set objUpdate = objResult.Updates.Item(I) WScript.Echo I + 1 & "> adding: " & objUpdate.Title objColUpdates.Add(objUpdate)NextWScript.Echo vbCRLF & "Downloading updates..."Set objDownloader = objSession.CreateUpdateDownloader() objDownloader.Updates = objColUpdatesobjDownloader.Download()WScript.Echo vbCRLF & "List of downloaded updates:"For I = 0 To objResult.Updates.Count-1 Set objUpdate = objResult.Updates.Item(I) If objUpdate.IsDownloaded Then WScript.Echo I + 1 & "> " & objUpdate.Title End IfNextSet objColUpdates = CreateObject("Microsoft.Update.UpdateColl")WScript.Echo vbCRLF & "Creating collection of downloaded updates to install:" For I = 0 To objResult.Updates.Count-1 set objUpdate = objResult.Updates.Item(I) If objUpdate.IsDownloaded = true Then WScript.Echo I + 1 & "> adding: " & objUpdate.Title objColUpdates.Add(objUpdate) End IfNextIf UCASE(strInstall) = "Y" Then WScript.Echo "Installing updates..." Set objInstaller = objSession.CreateUpdateInstaller() objInstaller.Updates = objColUpdates Set errRTN = objInstaller.Install() 'Output results of install WScript.Echo "Installation Result: " & funError(errRTN.ResultCode) WScript.Echo "Reboot Required: " & errRTN.RebootRequired & vbCRLF WScript.Echo "Summary of updates installed and results:" For I = 0 to objColUpdates.Count - 1 WScript.Echo I + 1 & "> " & _ objColUpdates.Item(i).Title & ": " & funError(errRTN.GetUpdateResult(i).ResultCode) NextElse WScript.Echo "You have elected to NOT install the updates at this time" & VbCrLf & _ "They have, however, been downloaded to the local cache."End If Sub subCheckCscriptIf UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" Then Wscript.Echo "This script must be run under CScript" WScript.QuitEnd Ifend SubSub subCheckArgumentsWScript.Echo "checking arguments"If colNamedArguments.Count < 3 Then If colNamedArguments.Exists("?") Then WScript.Echo "Try this: cscript " & WScript.ScriptName _ & VbCrLf & "Arguments are: [/i:install <y>] " _ & VbCrLf & "Example: cscript " & WScript.ScriptName & " /i:y" WScript.Quit End If If Not colNamedArguments.exists("i") Then WScript.Echo "Updates will NOT be installed. They will be enumerated" & VbCrLf &_ "To automatically install try this: " & VbCrLf & "cscript " & _ wscript.ScriptName & " /i:y" End If If colNamedArguments.exists("i") Then WScript.Echo "Updates will be installed automatically" & VbCrLf &_ "If this is not your wish, then press ^c to end the script" End IfEnd IfEnd SubFunction funError(strIN)Select Case strIN Case 0 funError = "Not Started" Case 1 funError = "In Progress" Case 2 funError = "Succeeded" Case 3 funError = "Succeeded with Errors" Case 4 funError = "Failed" Case 5 funError = "Aborted" Case Else funError "Error " & strIN & " is unknown"End SelectEnd Function
When you run SearchDownloadInstallWindowsUpdate.vbs, run it under Cscript. Interestingly enough, you can run Cscript inside a Windows PowerShell prompt:
Well, this brings our week to an end. Join us next week for more scripting fun and excitement. If you want to see what we will be up to, follow us on Twitter or on Facebook. If you get stuck trying to make your script work, you can also seek advice from your fellow scripters on the Official Scripting Guys Forum. Of course, you are always welcome to send us e-mail at scripter@microsoft.com. Until next week, keep cool and enjoy the weekend.
Ed Wilson and Craig Liebendorfer, Scripting Guys
I have a variation of the script above that I adapted to shutdown services prior to updating the server. The script works on the majority of my servers. HOWEVER, for a select few, the script runs and does it's service shutdown thing, but when it gets to ....
Set objInstaller = objSession.CreateUpdateInstaller()
objInstaller.Updates = objColUpdates
Set errRTN = objInstaller.Install()
It doesn't install the updates, and the "reboot trigger" remains "false" and doesn't reboot the server.
Autoupdates is set to "Download but don't install unless I say so..."
checked the Event logs and no updates are installed.
I've checked the registry settings under HKEY_Local_Machine\Software\Policies\Microsoft\Windows\WindowsUpdates and it's sub AU and all settings are identical to a server that DOES work.
Is there a log somewhere I can look to see why this "thinks" it's updating the server but doesn't?