Chapter 8 PowerShell and the File System

IN THIS CHAPTER

This chapter explains how PowerShell can be used to manage the Windows file system. This chapter provides examples on how to manage the file system using PowerShell. We discuss the core cmdlets; look at file system navigation; manage drives, folders and files; and show how to work with XML and CSV files. In addition, this chapter presents a working file-management script based on a real-world situation.

The goal is to give you a chance to learn how PowerShell scripting techniques can be applied to meet real-world file system automation needs.

Core Cmdlets

PowerShell provides a set of core cmdlets that can be used to manage all the various data stores that are supported via PowerShell Providers, which were discussed in Chapter 4, “Other Key PowerShell Concepts.” These core cmdlets can be used to manage all the supported data stores, so a consistent user experience is provided. If you need to create something in the registry or in the file system, the command and its syntax are similar.

NOTE

Some of the parameters to these cmdlets, and even some of the cmdlets themselves, might either require different arguments or possibly not work at all, depending on which provider is currently being used. For example, Select-String works differently while in the file system provider versus the registry provider. Unfortunately, there isn’t any help currently available that will dynamically update itself to let you know what will and will not work.

The following command retrieves a list of the core cmdlets for manipulating data stores available via PowerShell providers:

image

PS > help about_core_commands

image

Navigating the File System

PowerShell has a built-in provider, the PowerShell FileSystem Provider, for interfacing with the Windows file system. The abstraction layer this provider furnishes between PowerShell and the Windows file system gives the file system the appearance of a hierarchical data store. Therefore, interfacing with the file system is the same as with any other data store that’s accessible through a PowerShell provider.

Being able to move around in a file system is one of the most essential tasks in PowerShell. Several core cmdlets deal with file system navigation. For individuals more familiar with either DOS or UNIX/Linux servers, PowerShell offers aliases in most cases that are more familiar to users who are just getting accustomed to using PowerShell. The two key cmdlets when dealing with file system navigation are Set-Location (alias cd) and Get-Location (alias pwd).

Get-Location Cmdlet

The Get-Location cmdlet retrieves the current working directory. As you move through the file system, if you have changed your default PowerShell prompt, it can be useful to have a quick reminder of your current location in the file system.

image

PS > get-location
C:

image

Set-Location Cmdlet

The Set-Location cmdlet accepts a parameter that sets the working directory to the value specified. Using Set-Location enables one to move through the file system, and when you might need to access a file or run a script, only the relative file name needs to be used (versus the full path).

image

PS > get-location
C:
PS > set-location "C:documents and settings"
PS > get-location
Path
---------------------
C:documents and settings
PS >

image

NOTE

Tab completion works well with Set-Location. Start off the desired path, and then hit the TAB key. Additionally, one can use tab completion to even complete a path containing subdirectories. For example, if you want to change to the directory “C:Documents and SettingsuserABCDesktop,” you can simply do

set-location"c:docu*userA*desk* [TAB].

As long as the preceding string leads to a unique path, PowerShell auto-completes the entire string.

Push-Location Cmdlet

The Push-Location cmdlet, along with the Pop-Location cmdlet reviewed in the next section, are useful when navigating to and from multiple directories. Using Push-Location, we can have PowerShell remember certain directories for later use. Here’s a simple example of “pushing” the current directory to a list of locations.

image

PS >  get-location

Path
----
C:Documents and Settingsma36788


PS > push-location

image

Pop-Location Cmdlet

In the previous section, we saw how to push a directory onto a list of locations. Now, we are going to recall the last location remembered using Pop-Location.

image

PS > get-location

Path
----
C:Documents and Settingsma36788


PS > push-location
PS > cd c: emp
PS > get-location


Path
----
C: emp

PS > pop-location
PS > get-location

Path
----
C:Documents and Settingsma36788

image

Managing Drives

PowerShell drives can be created and removed, which is handy when you’re working with a location or set of locations frequently. Instead of having to change the location or use an absolute path, you can create new drives (also referred to as “mounting a drive” in PowerShell) as shortcuts to those locations.

Adding a Drive

To add a new drive, or a shortcut in this case, use the New-PSDrive cmdlet, shown in the following example:

image

Image

image

Removing a Drive

To remove a drive, use the Remove-PSDrive cmdlet, as shown here:

image

Image

image

Managing Folders

Let’s look at how to manage folders in PowerShell. Some cmdlets behave a bit differently depending on the provider. Dealing with folders while in a file system provider is easy to comprehend. In most cases, the arguments passed to the cmdlet are similar when dealing with a folder versus a file. This section examines folder management, and the next section covers file management.

Adding a Folder

To create a new folder, the New-Item cmdlet is used. We pass it a Type parameter with a value of Directory to indicate this will be a directory.

image

PS > new-item -type directory -path testing
    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo
Mode                LastWriteTime     Length Name
----                       -------------            ------      ----
d----          2/7/2008  10:30 PM                 testing
PS >

image

Removing a Folder

Removing a folder is just as easy using the Remove-Item cmdlet with the proper parameters and values.

image

PS > new-item -type directory -path testing
    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo
Mode                LastWriteTime     Length Name
----                          -------------             ------       ----
d----          2/7/2008  10:35 PM                  testing
PS > new-item -type file -path testingfoo
    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo esting
Mode                LastWriteTime     Length Name
----                        -------------               ------       ----
-a---          2/7/2008  10:35 PM          0       foo
PS > remove-item -path testing
Confirm
The item at C:demo esting has children and the Recurse parameter was
not specified. If you continue, all children
will be removed with the item. Are you sure you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "Y"):
PS >

image

NOTE

When creating a file or a folder, you want to specify the type as either directory or file. We see how to use new-item to create a file later.

The previous example shows what happens when we try to delete a directory that has some contents. If the testing directory were empty, there would be no output.

NOTE

Remember to use whatIf and confirm parameters when available to make any kind of change, such as deleting. You are either presented with the details of what PowerShell would have done had you entered the command as is or be prompted with an “Are you sure?” response before PowerShell continues with the command entered.

Moving a Folder

Let’s look at how to move a folder. Moving something consists of actually moving a directory, in this case, from some directory to another. In other words, you won’t typically use the Move-Item cmdlet to simply move the folder test to test2, which is basically renaming a folder, which we will see just after this.

image

PS > move-item bar c: emp
PS > get-item c: empar
    Directory: Microsoft.PowerShell.CoreFileSystem::C: emp
Mode                LastWriteTime     Length Name
----                           -------------               ------ ----
d----         1/15/2008   3:59 PM                       bar
PS > get-childitem c: empar
    Directory: Microsoft.PowerShell.CoreFileSystem::C: empar
Mode                LastWriteTime     Length Name
----                              -------------             ------ ----
-a---         1/29/2008  10:24 PM          6      fooing.txt
PS >

image

In the previous example, we moved a directory to a new location. It’s important to check that it has been moved. Notice that we first used Get-Item, and then Get-ChildItem. Get-Item simply lists an item itself, whereas Get-ChildItem lists the child items, such as files.

NOTE

When dealing with the Move-Item cmdlet, if you want to move directories recursively, especially when wanting to reproduce the directory structure from the source to the destination, it is easier to use the DOS xcopy command. PowerShell can handle this kind of operation, but several lines of scripting are required.

Renaming a Folder

In contrast with actually moving a folder, where it may be moved from one directory to a completely different location, renaming a folder would be more appropriate to use when the location of a folder will remain constant, but we are looking to change the name of the folder.

We say it is more appropriate to use Rename-Item, but Move-Item would be equally useful.

image

PS > new-item -type directory -path foo
    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          2/8/2008  12:32 AM            foo
PS > rename-item foo foobar
PS > get-item foobar

    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          2/8/2008  12:32 AM            foobar
PS >

image

Testing for a Folder

You might need to check whether a directory actually exists, especially in scripts dealing with any kind of file system management task. Using Test-Path returns a Boolean value (either “True” or “False”) depending on the result of the test.

image

PS > get-item foobar
    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          2/8/2008  12:32 AM            foobar


PS > test-path foobar
True
PS > test-path some_invalid_dir
False
PS >

image

A good practical example that we show is checking for the existence of a directory before continuing to run a script. In this case, we create a simple function to show how this works.

image

PS > function test_path {
>> if(!(test-path some_invalid_path)){
>> "Path not found"
>> break
>> }
>> "After if condition"
>> }
>>
PS > test_path
Path not found
PS >

image

We see that our function ended when we test for the existence of a file. If the file doesn’t exist, which we determine using "(if(!(",we run that statement block that outputs some text and then the break statement is invoked, which exits the function.

NOTE

In some cases, you want to make sure you use the pathType parameter. It takes the arguments leaf, for a file, container, for a directory, or any.

Managing Files

We looked at how to manage folders with PowerShell. Now, we look at how to manage files. Because of how PowerShell tries to provide a common experience to users, the cmdlets used will be the same for managing files versus managing folders. The only differences are found in the values passed to the arguments of the cmdlets.

Creating a File

The process to create a new file is basically the same as creating a new folder except a different value for a parameter is used.

image

PS > new-item -type file -path abc

    Directory: Microsoft.PowerShell.CoreFileSystem::C:demo

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         2/10/2008   9:12 PM          0 abc

PS >

image

Removing a File

The syntax for removing a file is exactly the same as removing a file because there isn’t a parameter for specifying whether we are attempting to remove a file or a folder.

image

PS > remove-item def
PS >

image

NOTE

You can use the confirm parameter to get a confirmation prompt on the screen before PowerShell actually carries out the request command, or you can use the whatIf parameter to have PowerShell display the commands that would actually be executed if the parameter wasn’t passed.

Moving a File

Moving an item and renaming an item are two different things.

image

PS > move-item abc new_directory
PS >

image

NOTE

You typically use Move-Item when you want to move an item to a new directory. When you want to change the name of an item, you should be renaming it and not moving it.

Renaming a File

If we want to rename an item, we should not attempt to move it, but use Rename-Item.

image

PS > rename-item xyz lmn
PS >

image

Getting the Content of a File

Let’s examine the content in a file. To read the data inside of a file, we use the cmdlet Get-Content.

image

PS > get-content string.txt
testing
PS >

image

Setting the Content of a File

To write to a file, we have two cmdlets: Set-Content writes data to the file, Add-Content appends data to the file. It is important to remember the difference between these two or risk losing data. Writing data to a file can do two things: create the file with the appropriate data or overwrite any existing data in the file. We show how we can use the Set-Content cmdlet to demonstrate both scenarios. We also use the file string.txt we saw in the previous section.

image

PS > set-content string.txt "foo"
PS > get-content string.txt
foo
PS > set-content new_file.txt "foo"
PS > get-content new_file.txt
Foo

image

Appending Content to a File

Add-Content can do two things: It can add data to an existing file, but it can also create a new file and add the data to it.

image

PS > get-content string.txt
foo
2nd line
PS > add-content string2.txt "2nd line"
PS > get-content string2.txt
2nd line

image

Searching for Content in a File

Fortunately, there is a cmdlet to search for data within items. Select-String enables you to search for the contents of a file passed as an argument.

image

PS > get-content string.txt
foo
2nd line
PS > select-string -path string.txt -patt "2nd"

string.txt:2:2nd line

PS >

image

You will normally use this cmdlet for searching through files that you are passing via the pipeline.

image

PS > get-content string.txt|select-string -patt "2nd"

2nd line

PS >

image

NOTE

Searching for strings in multiple files: As we mentioned, we can look through data passed via the pipeline by passing the files to search to the Select-String cmdlet. This is useful when attempting to search recursively through a file system. If we wanted to search through a file system recursively, we would use Get-ChildItem to get the objects we were interested in, and then pass those objects along to Select-String.

PS > get-childitem . -rec *.txt|foreach-object{select-string $_ -patt "2nd"}string.txt:2:2nd line
string2.txt:1:2nd line
foobarstring2.txt:1:2nd line
PS >

NOTE

The Select-String cmdlets works with the file system provider, but does not work with the registry provider; therefore, you cannot use Select-String within the registry to search.

Testing for a File

If you want to check for the existence of a file, the Test-Path cmdlet can help you. When testing for a file, you should pass the value leaf to the pathType parameter to make sure you are looking for a file; otherwise, you could end up matching the name to a directory.

image

PS > test-path -type leaf testing.txt
True
PS >

image

Working with XML Files

Dealing with XML files is another one of PowerShell’s strengths. You can load XML data for handy viewing, and you can also edit them.

In the first part of this section, we walk you through various tasks with PowerShell where we create an XML file, and then edit it by adding to it and removing from it. While doing so, we reference an article that originally appeared in the February 2008 issue of TechNet Magazine, which you can find online at http://technet.microsoft.com/en-us/magazine/cc194420.aspx.

The online document used VBScript and the older Microsoft.XMLDOM object to handle XML tasks. We are going to use PowerShell and the .NET Framework’s System.Xml.XmlDocument class to provide an updated example.

NOTE

XML files are case-sensitive. A node named “Test” will not be seen by PowerShell as the same as “TEST.

NOTE

The 2.0 CTP2 has a few new feature relating to XML:

• A new cmdlet named ConvertTo-Xml. As of the release of the 2.0 CTP2, the built-in help was not complete for this new cmdlet.

Creating an XML File

We want to end up with an XML document that looks like this:

image

image

Here’s the code we use to create the previous document.

image

image

If we use Get-Content to load our newly created XML document, we see that we achieved the desired result shown in the previous example.

image

PS > get-content test.xml
<?xml version='1.0'?>
<itchecklist>
  <computeraudit>
    <computername>atl-ws-001</computername>
  </computeraudit>
</itchecklist>

image

Appending an XML File

We have our XML document, but now we want to modify it by adding to the original XML file.

image

image

Now, our document looks like this:

image

PS> get-content test1.xml
<?xml version="1.0"?>
<itchecklist>
  <computeraudit>
    <computername>atl-ws-001</computername>
  </computeraudit>
  <computeraudit>
    <computername>atl-ws-100</computername>
    <auditdate>03/18/2008 23:11:19</auditdate>
  </computeraudit>
</itchecklist>

image

Modifying an XML File

We have added to our XML document; now, let’s show how to modify existing data in our XML file.

image

image

We have just modified an existing node, and our XML document looks like the following:

image

PS> get-content test2.xml
<?xml version="1.0"?>
<itchecklist>
  <computeraudit>
    <computername>atl-ws-001</computername>
  </computeraudit>
  <computeraudit>

    <computername>atl-ws-100</computername>
    <auditdate>03/18/2008 23:11:57</auditdate>
  </computeraudit>
</itchecklist>

image

Deleting from an XML File

Let’s look at how we can delete an existing node from our XML file.

image

image

Our document looks like this with a child node removed, which is what our document looked like when we first created it:

image

PS> get-content test3.xml
<?xml version="1.0"?>
<itchecklist>
  <computeraudit>
    <computername>atl-ws-001</computername>
  </computeraudit>
</itchecklist>

image

Loading an XML File

Before we show how to load an XML file, let’s note what we did in the previous sections: We used the Get-Content cmdlet to read the contents of an XML-formatted file. Using this method provides us with contents of the XML-formatted file, but this isn’t useful except for reading the file.

The proper way to use the XML features included with PowerShell is to use the [XML] type shortcut (also known as type accelerator).

image

PS > [xml]$xml=get-content test2.xml

image

Processing an XML File

In the previous section, we loaded an XML file into the $xml variable. Let’s look at what we can do with our new variable.

image

PSH > $xml
xml                                                         itchecklist
---                                                         -----------
version="1.0"                                               itchecklist
PSH>$xml.itchecklist
computeraudit
-------------
{computeraudit, computeraudit}
PSH>$xml.itchecklist.computeraudit
computername
------------
atl-ws-001
atl-ws-100

image

We can walk through all the XML nodes in the document. An example that could be handy is looking through the XML output of the new Server Manager included with Windows 2008 for the roles and features on a system.

Using Import-CliXml and Export-CliXml

We cannot split the Import-CliXml and Export-CliXml cmdlets into their own section, so we cover them together here.

Import-CliXml and Export-CliXml cmdlets are provided to handle structured data helping to move data in and out of files. This can help, for example, when one might need to store data. When it comes time to reconstruct the original object, the original properties and values can be accessed, but some of the methods might no longer be available.

Let’s create a simple string and datetime object, and then use Export-CliXml to write this object to a XML-formatted file.

image

PS > "test"|export-clixml string.xml
PS > get-date|export-clixml date.xml

image

We’ve created two XML-formatted files, so let’s take a look at the contents of each.

image

PS > get-content string.xml
<Objs Version="1.1"
xmlns="http://schemas.microsoft.com/powershell/2004/04"><S>test</S></Objs>
PS > get-content date.xml
<Objs Version="1.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="RefId-0"><DT>2008-03-11T23:47:4
6.4163463-03:00</DT><MS><Obj N="DisplayHint" RefId="RefId-1">
<TN RefId="RefId-0"><T>Microsoft.PowerShell.Commands.Displ
ayHintType</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T>
</TN><ToString>DateTime</ToString><I32>2</I3
2></Obj></MS></Obj></Objs>

image

Some of the key things to take out of the previous contents follow:

• From string.xml: The pair <S> and </S> indicate that this is a string object.

• From date.xml: The pair <DT> and </DT> indicate that this is a datetime object.

From there, we can take these XML files and move them around from one system to another.

If we use the Import-CliXml cmdlet, we can reconstruct the original objects again.

image

PS > (import-clixml string.xml).gettype().fullname
System.String
PS > (import-clixml date.xml).gettype().fullname
System.DateTime

image

In the previous example, we see we now have our original objects back again. If the XML is imported into another system, the specific .NET class used would also need to exist on the destination system.

Working with CSV Files

PowerShell also has some built-in functionality for dealing with comma-separated value (CSV) files. Import-Csv reads in the file and creates objects based on the contents of the file.

NOTE

The 2.0 CTP2 has a few new features relating to CSV:

• A new cmdlet named ConvertTo-Csv. As of the release of the 2.0 CTP2, the built-in help was not complete for this new cmdlet.

• The existing Import-Csv and Export-Csv cmdlets now have a new Delimeter parameter, which provides support for delimeters other than “,”. See the built-in help for the cmdlet for more details.

We look at Import-Csv and show an example of reading in a file.

image

PS > get-content server.csv
server,ip
server1,10.10.10.10
server2,10.10.10.11
PS > import-csv server.csv
server                                                      ip
------                                                      --
server1                                                     10.10.10.10
server2                                                     10.10.10.11
PS >

image

Because these are objects, we can use cmdlets like Select-Object to get just specific properties. For example, my server.csv file might contain all kinds of information regarding each server, but we might need only a printout of the server column.

image

PS >  import-csv server.csv|select server
server
------
server1
server2
PS >

image

We also said something about objects being created when using Import-Csv. Using Get-Member, we can see these are added as properties to a custom object that PowerShell creates.

image

PS > import-csv server.csv|get-member server,ip
   TypeName: System.Management.Automation.PSCustomObject
Name   MemberType   Definition
----               ----------           ----------
server NoteProperty System.String server=server1
ip     NoteProperty System.String ip=10.10.10.10

image

Writing to a CSV File

You can also use PowerShell to create a CSV file from objects passed along the pipeline. For example, you can get a listing of all the processes on the machine and write out particular objects to a CSV file.

image

PS > get-process|export-csv process.csv

image

The previous example dumps a lot of information into the CSV file, so we might want to filter out some of the information by using select-object.

image

PS > get-process|select name,company|export-csv process.csv

image

NOTE

Export-Csv also accepts a noTypeInformation parameter that removes information on the particular object that has just been exported. For example, in the last example, this was printed to the beginning of the resulting file:

#TYPE System.Management.Automation.PSCustomObject

Scenario: Automating File System Management

ProvisionWebFolders.ps1 is a script provided as a complete working example of PowerShell being put to use for task automation. A working copy of this script can be found at www.informit.com/title/9789780768687187. You need to provide two parameters to run this script. First, TemplatePath should have its argument set to the source path of the template folder structure copied to new users’ Web folders. Second, ImportFile should have its argument set to the name of the CSV import file used to define new users and their Web folder locations. The command to run the ProvisionWebFolders.ps1 script, with sample output shown in Figure 8.1, follows:

image

PS D:Work> .ProvisionWebFolders.ps1 . emplate .users.csv

image

Figure 8.1. The ProvisionWebFolders.ps1 script being executed

Image

The ProvisionWebFolders.ps1 script performs the following sequence of actions:

1. The script verifies that the template folder path exists.

2. The script verifies that the import folder path exists.

3. The script imports the CSV file into the $Targets variable.

4. For each user in $Targets, the script copies the template folder structure to the new user’s Web folder.

5. The script sets permissions on each folder, such as the following:

• Administrators: Owner

• Administrators: FullControl

• System: FullControl

• NewUser: FullControl

The first code sample contains the header for the ProvisionWebFolders.ps1 script. This header includes information about what the script does, when it was updated, and the script’s author. Just after the header are the script’s parameters:

image

image

Notice how the throw keyword is being used in the param declaration to generate an error when a parameter does not have a defined argument. This technique is used to force a parameter to be defined by stopping execution of the script and providing the script operator with information about the required parameter using the Write-Host cmdlet. When using the Write-Host cmdlet, you can use the Foregroundcolor parameter, as shown in the previous code sample, to control the color of output text. This feature is handy for focusing attention on details of the script status, as shown in Figure 8.2:

Figure 8.2. Colored console output text being used to convey script status

Image

Next, as seen in the following code sample, the script loads the needed file system management functions into its scope:

image

image

NOTE

The preceding functions are used to make file system permission changes. These functions are explained in Chapter 9, “PowerShell and Permissions.”

The next code sample contains the beginning of the script’s automation portion. First, the script checks to see if the string contained in the $TemplatePath variable is a valid folder path. Then, the script checks to see if the string contained in the $ImportFile variable is a valid file path. To perform these tests, the if...then statements make use of Test-Path cmdlet. This is a handy cmdlet that can be used for verifying whether a folder or file (-pathType container or leaf) is valid. If any of these paths are invalid, the script execution is halted, and information about the invalid paths is returned to script operator:

image

image

In the next code sample the rest of the variables that are used in the script are defined. The first variable $Owner is used by the script to define the owner for each user’s Web folder structure, which in this case is the local Administrators group. Then, the variable $Targets is defined using the Import-Csv cmdlet. This cmdlet is used to read values from the import CSV file ($ImportFile) into the $Targets variable, which is used to provision new users’ Web folders:

image

image

In the following code sample, the script uses the path and username information from the information contained in the $Target variable to construct the final destination path using the Join-Path cmdlet. Then, the script uses the Copy-Item cmdlet to copy the template folders to the destination path:

image

image

Next, the script uses the Set-Owner function to change ownership of the user’s Web folder structure to the local Administrators group:

image

image

You might be wondering why the code for Set-Owner is enclosed in a script block. The dot (.) call operator preceding the script block tells PowerShell to run the script block within the current scope. If the call operator isn’t used, PowerShell doesn’t run the script block. The reason for creating an independent script block to handle the code for Set-Owner is to ensure that the trap statement is scoped only to this block of code.

In the following code sample, notice that the Administrators group is added to the root folder’s security descriptor before inherited permissions are cleared:

image

image

The Clear-Inherit function clears inherited permissions from the root folder, subfolders, and files, in addition to explicitly defined permissions on all subfolders and files. If the Administrators group didn’t have explicitly defined rights on the root folder, the rest of the script wouldn’t run because of a lack of rights.

NOTE

Explicitly defined permissions are permissions that are directly defined for a user on an object. Implicitly defined permissions are permissions that are either inherited or defined through membership of a group.

In the last code sample, the SYSTEM account and the user are then granted FullControl to the user’s web folder, and the script notifies the script operator of its completion:

image

image

Summary

We first looked at the core cmdlets used when dealing with file systems. We discussed how these core cmdlets provide a common experience among different providers, not only when dealing with file systems.

Then, we focused on how to manage the Windows file system using PowerShell, where we showed how to complete some of the most common administrative tasks done with drives, folders, and files.

This chapter provided an overview of how to manage CSV and XML files using cmdlets created specifically to deal with these specially formatted files.

Finally, the chapter presented a complete file system management script gathering several key concepts already reviewed in the book. Modularizing scripts can provide various advantages, such as reusing code and helping to make scripts more readable.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset