Powershell - Get-PSDrive - How to add an alias for each "Name" function

This topic contains 14 replies, has 2 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 1 year, 8 months ago.

  • Author
    Posts
  • #26985
    Profile photo of Mel VW
    Mel VW
    Participant

    Hi,
    I need to come up with a way to show correct name for the server. For now, I would like to hard-code the server.
    For example, if the Name is A,
    then the name should be webserver001.
    If B
    then
    webserver002.

    This is my current command for it, but I am not sure how to add a column to represent the column names.

    `
    get-psdrive -PSProvider filesystem | Format-Table -Wrap -AutoSize -Property Root,@{Name="UsedGB";Expression={[math]::round($_.used/1gb,2)}}, @{Name="FreeGB";Expression={[math]::round($_.free/1gb,2)}}, @{Name="PctFree";expression={$_.free/($_.free+$_.used)*100 –as [int]}}
    `

    What is what it does:

    Root UsedGB FreeGB PctFree
    —- —— —— ——-
    A:\ 27.62 49.91 64
    B:\ 2.37 73.65 97
    C:\ 60.43 0.56 1
    D:\ 0 0
    E:\ 6.64 105.46 94
    F:\ 3.51 96.49 96
    G:\ 11.98 88.01 88
    H:\ 9.75 92.12 90
    I:\ 32.4 432.72 93
    J:\ 27.62 49.91 64
    K:\ 27.62 49.91 64
    Q:\ 7037.5 4137.5 37
    Z:\ 27.62 49.91 64

    This is what I want it to do:
    Root UsedGB FreeGB PctFree ServerName
    —- —— —— ——- web001
    A:\ 27.62 49.91 64 web002
    B:\ 2.37 73.65 97 web003
    C:\ 60.43 0.56 1 web004
    D:\ 0 0 web005
    E:\ 6.64 105.46 94 web006
    F:\ 3.51 96.49 96 web007
    G:\ 11.98 88.01 88 web008
    H:\ 9.75 92.12 90 web009
    I:\ 32.4 432.72 93 web010
    J:\ 27.62 49.91 64 web011
    K:\ 27.62 49.91 64 web012
    Q:\ 7037.5 4137.5 37 web013
    Z:\ 27.62 49.91 64 web014

  • #26988
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    You should setup an alias table. It could be done numerous ways with a PSObject or in this example a hashtable. You can build a hashtable manually for reference:

    $aliasTable = @{}
    $aliasTable.Add("A:\","Web1")
    $aliasTable.Add("B:\","Web2")
    $aliasTable.Add("C:\","Web3")
    $aliasTable.Add("D:\","Web4")
    $aliasTable.Add("E:\","Web5")
    $aliasTable.Add("F:\","Web6")
    $aliasTable.Add("G:\","Web7")
    $aliasTable.Add("H:\","Web8")
    

    Or if the servers are sequentially ordered as A = 1, B=2....you can build it dynamically using ASCII char codes (i.e. char code 65 is a capital A):

    $aliasTableV2 = @{}
    for ($i=1;$i -le 10;$i++){
        $aliasTableV2.Add([char]($i +64)+":\", "Web$i")
    }
    

    Once you have a lookup table, then it's as simple as:

    PS C:\Windows\System32\WindowsPowerShell\v1.0> $aliasTable.Get_Item("F:\")
    Web6
    

    You command would look like this:

    Get-PSDrive -PSProvider FileSystem | 
    Format-Table -Wrap -AutoSize -Property Root,
                                           @{Name="UsedGB";Expression={[math]::round($_.used/1gb,2)}}, 
                                           @{Name="FreeGB";Expression={[math]::round($_.free/1gb,2)}}, 
                                           @{Name="PctFree";Expression={$_.free/($_.free+$_.used)*100 –as [int]}}
                                           @{Name="Server";Expression={$aliasTable.Get_Item($_.Root)}}
    
  • #26989
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    If they are sequential, another approach is foregoing the alias table and reversing what I did above with subtraction versus addition to get the server number:

    $root = "G:\"
    "Web" + ([int][char]($root -Split ":")[0] -64)
    

    Get the drive (G:\), split it at the semicolon into an array, get the first index (i.e. G), subtract 64 and convert the character code to an integer. Somewhat complex, but it works and no alias table is needed (seems like the coffee is working this morning):

    Get-PSDrive -PSProvider FileSystem | 
    Format-Table -Wrap -AutoSize -Property Root,
                                           @{Name="UsedGB";Expression={[math]::round($_.used/1gb,2)}}, 
                                           @{Name="FreeGB";Expression={[math]::round($_.free/1gb,2)}}, 
                                           @{Name="PctFree";Expression={$_.free/($_.free+$_.used)*100 –as [int]}}
                                           @{Name="Server";Expression={"Web" + ([int][char]($_.Root -Split ":")[0] -64)}}
    
  • #26990
    Profile photo of Mel VW
    Mel VW
    Participant

    And what if i needed to add another column for description, how would I do that?

  • #26991
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    That wasn't part of the original requirements. Keep in mind $alias is a manually generated PSObject. You could put this data in a CSV and use Import-CSV the same way.

    $alias = @()
    $alias += New-Object -TypeName PSObject -Property @{DriveLetter="A:\";WebServer="Web1";Description="This is for website foo.com"}
    $alias += New-Object -TypeName PSObject -Property @{DriveLetter="B:\";WebServer="Web2";Description="This is for website moo.com"}
    
    
    Get-PSDrive -PSProvider FileSystem | 
    Format-Table -Wrap -AutoSize -Property Root,
                                           @{Name="UsedGB";Expression={[math]::round($_.used/1gb,2)}}, 
                                           @{Name="FreeGB";Expression={[math]::round($_.free/1gb,2)}}, 
                                           @{Name="PctFree";Expression={$_.free/($_.free+$_.used)*100 –as [int]}}
                                           @{Name="Server";Expression={$root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty WebServer}}
                                           @{Name="Description";Expression={$root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty Description}}
    

    If the information was in AD for the description, you could also use Get-ADComputer with the original hashtable and do something like this:

    @{Name="Description";Expression={Get-ADComputer -Identity ("Web" + ([int][char]($root -Split ":")[0] -64)) -Properties Description | Select -ExpandProperty Description}}
    
  • #26992
    Profile photo of Mel VW
    Mel VW
    Participant

    I am running on Version 2.

    PS C:\_> get-host

    Name : ConsoleHost
    Version : 2.0
    InstanceId : 22110d0d-7482-4969-800c-93f2d73a9ace
    UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
    CurrentCulture : en-US
    CurrentUICulture : en-US
    PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
    IsRunspacePushed : False
    Runspace : System.Management.Automation.Runspaces.LocalRunspace

    i am getting this as a response:
    `
    PS C:\_> .\foo.ps1

    Root UsedGB FreeGB PctFree
    —- —— —— ——-
    A:\ 30.31 47.22 61
    B:\ 2.39 73.63 97
    C:\ 60.43 0.56 1
    D:\ 0 0
    E:\ 7.25 104.85 94
    F:\ 4.52 95.47 95
    G:\ 12.11 87.89 88
    H:\ 11.98 89.89 88
    I:\ 46.35 418.78 90
    J:\ 30.31 47.22 61
    K:\ 30.31 47.22 61
    Q:\ 7046.18 4128.82 37
    Z:\ 30.31 47.21 61

    Name Value
    —- —–
    Name Server
    Expression $root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty WebServer
    Name Description
    Expression $root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty Description

    `

  • #26993
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Commas were missing on for the added calculated properties:

    $alias = @()
    $alias += New-Object -TypeName PSObject -Property @{DriveLetter="A:\";WebServer="Web1";Description="This is for website foo.com"}
    $alias += New-Object -TypeName PSObject -Property @{DriveLetter="B:\";WebServer="Web2";Description="This is for website moo.com"}
    
    
    Get-PSDrive -PSProvider FileSystem | 
    Format-Table -Wrap -AutoSize -Property Root,
                                           @{Name="UsedGB";Expression={[math]::round($_.used/1gb,2)}}, 
                                           @{Name="FreeGB";Expression={[math]::round($_.free/1gb,2)}}, 
                                           @{Name="PctFree";Expression={$_.free/($_.free+$_.used)*100 –as [int]}},
                                           @{Name="Server";Expression={$root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty WebServer}},
                                           @{Name="Description";Expression={$root = $_.Root; $alias | Where{$_.DriveLetter -eq $root} | Select -ExpandProperty Description}}
    
  • #27009
    Profile photo of Mel VW
    Mel VW
    Participant

    Instead of using drive letters, what if it was server ip addresses used instead?

  • #27010
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Can you provide what you are actually doing? What you data you are working with and the expected end results? The community is here to assist, but vague requirements will just waste time.

  • #27013
    Profile photo of Mel VW
    Mel VW
    Participant

    I need to check disk space capacity on 30 servers. Ideally using IP Addresses would work better.

    I have used the following but struggle to get to custom columns to indicate info on what is hosted on each server i.e. like the previous post regarding adding a column for the domain name and the description.

    below is something i am using

    `
    $ServerName = Get-Content "C:\_\servers.txt"
    $Partition = Get-Content "C:\_\partition.txt"
    $ConvertToGB = (1024 * 1024 * 1024)

    "Server" + " " + "Size" + " " + "Free" + " "

    foreach ($Server in $ServerName) {
    $disk = Get-WmiObject Win32_LogicalDisk -ComputerName $Server -Filter $Partition | Select-Object Size,FreeSpace
    $Server + " " + ([math]::round(($disk.Size / $ConvertToGB),2)) + " GB" + " " + ([math]::round((($disk.FreeSpace / $ConvertToGB)),2)) + " GB"
    }
    `

    The server.txt files contains ip addresses of each server

    format inside text file

    192.142.1.1
    192.142.1.2
    192.145.6.4
    etc etc

    The partition txt file contains:
    DeviceID='C:'

    However, every server has a different letter for its hard drive.

    —-
    Bottom line that script which you created works but if could use ip addresses of the servers AND the Drive Letter of each server then we have winner.

  • #27016
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    If you are looking for a disk report, there are a lot of examples already created, such as:

    http://blogs.technet.com/b/heyscriptingguy/archive/2012/08/08/use-powershell-to-create-a-report-displaying-free-disk-space.aspx

    They will not care if you use an IP address or DNS name for a computer. As every system is different, it's probably simpler to not filter the partition and just pull all partitions on that server.

  • #27017
    Profile photo of Mel VW
    Mel VW
    Participant

    Thanks Rob much appreciated.

    Will have a look.

    Do you have examples of powershell scripts which use text files as an external source for references certain data like computer names or any data.

    and going line by line...tried foreach and for loop and it prints the entire data on file which is not what i wanted but line by line.

    text files or xml files ....any file for that matter.

  • #27018
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    There an tons of examples of what you are asking for.

    If a file is formatted like:

    Computer1
    Computer2

    foreach ($computer in (Get-Content C:\Computers.txt) { $computer }

    XML files is a bit ominous. Powershell can export data as XML, which can be imported using Import-CliXML. If you just want to parse XML data, there are many examples on working with XML using many methods such as XPath. You can also easily import CSV's with Import-CSV. If you are just starting, I would lookup Month Of Lunches book by Don Jones to help with understanding Powershell fundamentals.

  • #27031
    Profile photo of Mel VW
    Mel VW
    Participant

    Yeah, basically an idea is to have a configuration file for support and system administrators to add or remove data.
    I think xml looks more in order because parameter names make it easier for humans to read.

  • #27069
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    You should take a look at JSON. It is similar to XML but as you appropriately put, it is supposed to be more "human readable". There is a ConvertTo-JSON and ConvertFrom-JSON to export and import data into Powershell respectively.

You must be logged in to reply to this topic.