Hey, Scripting Guy! How Can I Use Windows Power. Shell to Create a Text File with Fixed- Length Lines? Hey, Scripting Guy! I am trying to learn Windows Power. Shell 2. 0, but I am having some issues when it comes to string manipulation. I have been a faithful reader of the Scripting Guys for several years, and I have found many of the scripts to be critical in my business environment. Windows PowerShell Paradigm Multi-paradigm: Imperative, pipeline, object-oriented, functional and reflective Designed by Jeffrey Snover, Bruce Payette, James Truher.ps1 (Script).ps1xml (XML Document).psc1 (Console File). Recently I was tasked with creating a Cluster Health Report for the Windows 2008 R2 Clusters. I was able to do this with PowerShell using the failovercluster cmdlets. This was outputted to a text file and emailed to the support for. To read the contents of a text file, I like to use the Get-Content cmdlet. Because I renamed the original file to hsg62810.txt.old, I use the string “$file.old” as the path to the file. The Get-Content cmdlet returns an array of. I wish I could simply translate the VBScript scripts we use directly into Windows Power. Shell and not have to fool with learning the “Power. Shell way of doing things.” Why should I have to learn a whole new way of working with strings and files? I mean, if a Windows Power. Shell script works, is that not the “Power. Shell way?” It seems to me like you are letting a bunch of UNIX guys try to tell me how to administer my Windows servers.— RSHello RS,Microsoft Scripting Guy Ed Wilson here. One of the great things about being a Microsoft Scripting Guy is the ability to talk and to interact with customers. I always learn from these interactions. Sometimes I learn that I have not been clear about a particular topic, or I learn that a feature I was not too impressed with has solved a particular need for someone. Many times I learn new techniques, tricks, or tips that make me a better scripter. I am the first to admit I do not know everything there is to know about VBScript, WMI, ADSI, the . NET Framework, or Windows Power. Shell. The topics are too big, and I do not believe that anyone knows everything about scripting. The truly great thing about Windows Power. Shell is that you do not need to know everything about Windows Power. Shell to write a script that works. This is also both a cool thing and a frustrating thing. Let me explain a little bit. Many times I spend hours working on a script only to have someone pop up and say, “Why didn’t you do such and such?” Quite often, their suggestion takes my 3. Does this mean my script is “wrong” and theirs is “right”? Not at all. If a script works, it works. If a script solves your problem, it has done its job. Can a script be made better? In nearly every case the answer is yes. What is the best script? Well, that depends on your criteria. Here are some common criteria for judging scripts: Shortest amount of code Shortest amount of development time Most robust (ability to run in many different environments) Easiest to read Most maintainable Easiest to troubleshoot Most reusable Easiest to use As you can see, the many ways to judge the best script are almost as varied as the number of different people writing scripts. To directly answer your question, in most cases you can in fact make a Windows Power. Shell script seem like a VBScript. If this works for you, by all means go for it. The thing is that in many cases Windows Power. Shell has the ability to make things much easier. You mentioned you do a lot of work with strings. Let’s take as an example a Hey, Scripting Guy! Blog post you may remember from the past: “How Can I Make Sure That No Line in a Text File Exceeds 2. Characters?” The VBScript from that article is shown here. Shorten. Lines. In. Text. File. vbs. Const For. Reading = 1 Const For. Writing = 2 Set obj. FSO = Create. Object(“Scripting. Here's what I would do: Get-Content.\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Snark's line does the same, but it starts with loading all of the file into an array, which may be problematic with big files memory-wise. The simple solution is to avoid creating an array before piping to out-file. Rule # 1 of powershell is that the comma is a special delimiter and the default behavior is to create an array. Concatenation is done like this.. File. System. Object”) Set obj. File = obj. FSO. Open. Text. File (“C: HSGhsg. For. Reading) Do Until obj. File. At. End. Of. Stream str. Line = obj. File. Read. Line str. Line = Left(str. Line, 9) str. Contents = str. Contents & str. Line & vb. Cr. Lf Loop obj. File. Close Set obj. File = obj. FSO. Open. Text. File(“c: scriptstest. For. Writing) obj. File. Write str. Contents obj. File. Close. The script is designed to read a text file that contains lines of varying lengths, and shorten the lines to a specific length (9 characters, in this example). If the line is shorter than 9 characters, that is okay and there is no requirement for line padding. The text file in question is shown in the following image. After the script has run, the text file shown in the following image is created. To translate this script to Windows Power. Shell requires very little effort. The key things to remember are that in Windows Power. Shell new objects are created by the New- Object cmdlet, and that variables have a dollar sign in front of them. Oh yeah, the Do…Until loop does not have a loop command. One of the key tricks to making a translated VBScript is getting the ability to use the VBScript functions. Windows Power. Shell does not have a Left command that is used for string manipulation. It has a substring method from the . NET Framework string class. To gain access to the VBScript string functions, load the microsoft. Add- Type cmdlet (in Windows Power. Shell 1. 0, you used the reflections. NET Framework class). To make using Left easier, create an alias for the microsoft. NET Framework class. These two commands are shown here: add- type - Assembly. Name microsoft. visualbasic $strings = “microsoft. In VBScript, there were two concatenation operators: the + and the &. In Windows Power. Shell, there is only the + character. In VBScript, you had the VBCRLF operator; Windows Power. Shell uses “`r`n” to accomplish the same thing. To make the script as similar to the VBScript as possible, I created the variable $Vb. Cr. Lf and set it equal to “`r`n” as shown here: $Vb. Cr. Lf = “`r`n”The complete Shorten. Lines. In. Text. File. Trans. Fm. VBS. ps. Shorten. Lines. In. Text. File. Trans. Fm. VBS. ps. 1add- type - Assembly. Name microsoft. visualbasic $strings = “microsoft. Vb. Cr. Lf = “`r`n” $for. Reading = 1 $for. Writing = 2 $obj. FSO = New- Object - Com. Object scripting. File = $obj. FSO. Open. Text. File(“C: HSGhsg. Reading) Do { $str. Line = $obj. File. Read. Line() $str. Line = $strings: :Left($str. Line, 9) $str. Contents = $str. Contents + $str. Line + $Vb. Cr. Lf } Until($obj. File. At. End. Of. Stream) $obj. File. Close() $obj. File = $obj. FSO. Open. Text. File(“C: HSGhsg. Writing) $obj. File. Write($str. Contents) $obj. File. Close()Another way to write this script that takes advantage of some of the features of Windows Power. Shell is seen in the Create. File. With. Lines. Of. Specific. Length. I decided to add one improvement to the script, and that is to make a backup copy of the file before modifying the original text file. After assigning the path to the file, I use the Rename- Item cmdlet to rename the original file to hsg. To do that, I take advantage of the expanding string feature in Windows Power. Shell. When a variable is placed inside double quotation marks, it automatically expands to display the value that is contained inside the variable. This makes it really easy to do things such as append new file extensions to original file names. This is shown here inside the Windows Power. Shell console where the path is assigned to the $file variable, and then the file with a new extension is displayed. Note that this does not assign a new value to the $file variable, but just displays a string with . This is shown here: PS C: > $file = “C: fsohsg. PS C: > “$file. C: fsohsg. 62. 81. PS C: > To read the contents of a text file, I like to use the Get- Content cmdlet. Because I renamed the original file to hsg. I use the string “$file. The Get- Content cmdlet returns an array of strings. This array of strings is sent down the pipeline to the Foreach- Object cmdlet. In the Foreach- Object cmdlet, the if statement is used to check the length of each line as it comes down the pipeline. The $_ automatic variable is used as a placeholder in the Foreach- Object cmdlet to allow us to work with the lines of text as they come down the pipeline. Each line of text is an instance of the system. NET Framework class, which has a length property that indicates how many letters are in the string. If the length is less than or equal to (- le operator) 9 characters, the line of text is added to the newly created hsg. The new file will be automatically created by the Add- Content cmdlet. The text that is written to the file is the string represented by the $_ variable. This section of the script is shown here: For. Each- Object { if($_. Path $file - Value $_ }If the line of text is longer than 9 characters, the system. There are two parameters for the substring method. The first one is the starting position, and the second parameter is the number of characters to return. This is very similar to the VBScript function mid. An example of using the VBScript function mid is shown here: Dim My. Var. My. Var = Mid(“VB Script is fun!”, 4, 6) ‘ My. Var contains “Script”. The same substring command is shown here. You will notice that Windows Power. Shell begins numbering at 0 for the starting position: PS C: > $myvar = “VB Script is fun!” PS C: > $myvar. Substring(4,6)Script. PS C: > $myvar. Substring(3,6)Script. PS C: > The cool thing is that because everything in Windows Power. Shell is an object, a string is in reality already an instance of the system. NET Framework class. This means the substring method is immediately available on any string. You do not even have to put parentheses around the string first. This is shown here: PS C: > “VB Script is fun!”. Script. PS C: > The Add- Content cmdlet automatically appends to a text file, and there is no need to add any special parameters to cause this action. The line from the script that selects nine characters from the beginning of the line of text on the pipeline and writes it to the text file is shown here: { Add- Content - Path $file - Value $_. Substring(0,9) }The complete Create. File. With. Lines. Of. Specific. Length. Create. File. With. Lines. Of. Specific. Length. ps. 1$file = “C: fsohsg. Rename- Item - Path $file - New. Name “$file. old” Get- Content - Path “$file. For. Each- Object { if($_. Path $file - Value $_ } Else { Add- Content - Path $file - Value $_. Substring(0,9) } }RS, that is all there is to using Windows Power. Shell to create a file with fixed- length lines. String Migration Week will continue tomorrow. If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. How to use Power. Shell to create HTML from a Text File. Posted by newlife. Oct 9, 2. 01. 2 in Powershell | 7 comments. Recently I was tasked with creating a Cluster Health Report for the Windows 2. R2 Clusters. I was able to do this with Power. Shell using the failovercluster cmdlets. This was outputted to a text file and emailed to the support for review daily. To expand / enhance the report it was suggested to create it in HTML format. So back to Power. Shell we go and low and behold we find the Convert. To- Html cmdlet. Looking at the get- help and document one would think that using the command is straight forward, but in reality it is a bit more to it. For example, we could passget- service | convertto- html - as LIST > c: \temp\services. Pretty simple, right? That’s what I thought, so my inclination was to feed it the text file to Convert. To- Html and Get_content and I will have a finished product.$Source. File = "C: \Support\clustercheck. Target. File = "C: \Support\clustercheck. Get- Content $Source. File | Convert. To- Html | Out- File $Target. File. No such dice, what I received was a bunch of garbage output. Upon further research found rather than just wrapping text in HTML, Convert. To- Html will output properties of objects to HTML. When reading the file using Get- Content you end up with an array of string objects. These objects are being passed to Convert. To- Html through the pipe. The string objects contain properties. And these properties are being output to the HTML. In order to use Convert. To- Html we will need to create objects that would contain text lines as properties. So things just got a bit more complicated. What we have to do is read each line of the text file and create a PSObject and add- member for each of the lines, then run Convert. To- HTML. What you end up with is this code.$Source. File = "C: \Support\clustercheck. Target. File = "C: \Support\clustercheck. File = Get- Content $Source. File. $File. Line = @(). Foreach ($Line in $File) {. My. Object = New- Object - Type. Name PSObject. Add- Member - Input. Object $My. Object - Type Note. Property - Name Health. Check - Value $Line. File. Line += $My. Object. $File. Line | Convert. To- Html - Property Health. Check - body "< H2> Cluster Healthcheck< /H2> " | Out- File $Target. File. Now when it is ran we get what we were looking for in the first place. So no we have a start towards an HTML outputted report. So if we wanted to make the report look nicer we could pass formatting in the Convert. To- Html cmdlet. Using the above snippet as a shell you can use any text file to create html formatted reports in Power.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
October 2016
Categories |