Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Wednesday, February 18, 2015

Getting Hard Drive Information from Remote Clients

Today on LinkedIn, I noticed that someone was trying to get hard drive information and then save it to a CSV file.  I believe the purpose was to present the data in Excel.  Nothing wrong with this, but it does raise a few questions.

1. What if there is an inconsistent number of drives on the client?

2. Is the client online?

3. Do you want all drives, or just the fixed drives?

4. How to maintain a list of clients that were offline at the time?

The two big things for me are the multiple hard drives question and the “what if” the client is offline question.  When it comes down to an unknown number of objects being returned, XML is really the way to go.  It allows me to create a single property at the root of the object that can hold that unknown number of child objects (multiple hard drives).  Also, I may need to account for clients that were offline.  My data will have a property called Online that will be set to TRUE or FALSE.  That way I can feed that data file through again and be able to execute against just those clients that were offline during the previous run.  That will save time and prevent a duplication of data.  Get ready, this is a big hunk of code.  In all actuality, much of it is one of my templates. To learn more about how to use it, check out the help file.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

Function Get-HDSizeInfo

{

[CmdletBinding()]

Param(

   

    [parameter(Mandatory=$true,

                ValueFromPipeline=$true,

                ValueFromPipelineByPropertyName=$true)]

    [String[]]

    $ComputerName,

 

    [Switch]

    $Fixed   

   

    )

 

BEGIN

{

    # Place all private functions here.

 

    # Main Object Creation

    Function New-CustomObject

    {

        $Obj = New-Object -TypeName PSObject -Property @{

            "ComputerName" = $Null

            "Online" = $False

            "Drives" = $Null

        }

        $obj.PSObject.TypeNames.Insert(0,'HDInfo')

        Write-Output $Obj

    }

 

}

PROCESS

{

    # Get a fresh copy of the output object.

    $CustomeObject = New-CustomObject

 

    # Cycle through each client and process.

    ForEach ($C in $ComputerName)

    {

        Write-Verbose "Connecting to: $C"

 

        # Initialize the output data.

        $Data = $CustomeObject

 

        # Add the name of the current client being processed to the Object.

        $Data.ComputerName = $C

     

        Try

        {

            # Establish the PowerShell Session

            $SO = New-PSSessionOption -OpenTimeout 500 -NoMachineProfile

            $SessionHash = @{

                "ComputerName" = $C

                "SessionOption" = $SO

                "ErrorAction" = "Stop"

            }

         

            # Establish the new session.

            $S = New-PSSession @SessionHash

 

            # Execute on the remote client.

            $Hash = @{

                "Session" = $S

                "ArgumentList" = $CustomeObject

            }

            $Data = Invoke-Command -Session $S -ScriptBlock {

                Param ($Obj, $Fixed)

                # Place all code to run remotely here.

     

                # Function to create the Hard Drive Object.

                # This function will run for each discovered drive.

                Function New-HDObject

                {

                    $Obj = New-Object -TypeName PSObject -Property @{

                        "Drive" = ""

                        "SizeGB" = 0

                        "UsedGB" = 0

                        "FreeGB" = 0

                    }

                    $obj.PSObject.TypeNames.Insert(0,'HDInfo.Drive')

                   

                    # Send the object to the calling statement.

                    Write-Output $Obj

                } # END: Function New-HDObject

 

                # Set the ComputerName.

                $Obj.ComputerName = HostName

           

                # Mark the client as being "Online"

                $Obj.Online = $True

 

                # Get the Hard Drive Info.

                If (!($Fixed))

                {$Drives = Get-CimInstance Win32_LogicalDisk}

                Else

                {$Drives = Get-CimInstance Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3}}

 

                # Cycle through each drive and add the drive info to the array.

                $DInfo = @()

                ForEach ($D in $Drives)

                {

                    $SingleDrive = New-HDObject

                    $SingleDrive.Drive = $D.Caption

                    $SingleDrive.SizeGB = $D.Size/1gb

                    $SingleDrive.UsedGB = ($D.Size-$D.FreeSpace)/1gb

                    $SingleDrive.FreeGB = $D.FreeSpace/1gb

 

                    # Add this drive to the $DInfo Array.

                    $DInfo += $SingleDrive

                }

 

                    # Add the $DInfo array to the "Drives" Property.

                    $Obj.Drives = $DInfo

 

                # Return the object to the calling client.

                Write-Output $Obj

 

                # End of remote commands.

            } -ArgumentList $Data, $Fixed

       

            # Remove the PS Session.

            $S | Remove-PSSession

 

            Write-Verbose "Finished processing: $C"

        } # END: TRY BLOCK

        Catch

        {

        Write-Verbose "Error connecting to: $C."

        $Data.ComputerName = $C

        } # END: CATCH BLOCK

        

        # Write the data to the pipeline.

        Write-Output $Data

    }

} # END: Process

END{} # END: END BLOCK

 

<#

.SYNOPSIS

Returns data on remote hard drives.

 

.DESCRIPTION

Utilizes PowerShell Remoting to access hard drive information on remote computers. 

This cmdlet returns information on each drive for size, free space, and used space.

 

.PARAMETER ComputerName

The name of the client to recover drive information from.

 

.PARAMETER Fixed

Returns only local fixed hard drives.

 

.EXAMPLE

Get-HDSizeInfo -ComputerName Cl1, DC2, EX1, DC1 -Fixed

 

Returns the fixed hard drive information for clients CL1, DC2, EX1, and DC1.

 

.EXAMPLE

Get-ADComputer -Filter * | Select-Object -Property @{N="ComputerName";E={$_.Name}} | Get-HDSizeInfo

 

Returns the drive information for all clients listed in an Active Directory Domain.

You must have access to the Active Directory module from Windows PowerShell to

execute this example.

 

.EXAMPLE

Get-HDSizeInfo -ComputerName Ex1, DC1 | Export-Clixml -Path "HDData.XML"

 

Get's hard driving information for two clients and exports the data to an XML file.

 

.EXAMPLE

Import-Clixml -Path "HDData.xml" | Where Online -eq $False | Get-HDInfo

 

Reads and XML file produced by a previous run of this cmdlet and executes

against clients that were offline during the previous run.

 

.NOTES

Requirements:

- PowerShell Remoting is enabled.

- You are logged on with credentials that allow you to remote to other clients.

===============================================================================

== Cmdlet: Get-HDSizeInfo                                                    ==

== Author: Jason A. Yoder                                                    ==

== Company: MCTExpert of Arizona                                             ==

== Date: February 17, 2015                                                   ==

== Copyright: All rights reserved.                                           ==

== Version: 1.0.0.0                                                          ==

== Legal: The user assumes all responsibility and liability for the usage of ==

== this PowerShell code.  MCTExpert of Arizona, Its officers, shareholders,  ==

== owners, and their relatives are not liable for any damages.  As with all  ==

== code, review it and understand it prior to usage.  It is recommended that ==

== this code be fully tested and validated in a test environment prior to    ==

== usage in a production environment.                                        ==

==                                                                           ==

== Does this code make changes: NO                                           ==

===============================================================================

#>

} # End Function Get-HDSizeInfo

  

 

No comments: