简体   繁体   中英

Foreach-Object with HashTables?

I'm trying to check wheter some network drives are mapped via logon script. If they're not mapped, the script should be able to map them but My Foreach-Object in the code below doesn't work. why? Can't I use it on hashtables?

$Hash = @{
    "h:" = "\\server\share";
    "i:" = "\\server\share";
    "j:" = "\\server\share";
    "k:" = "\\server\share";
    "p:" = "\\server\share";
    "z:" = "\\server\share";
    }
        $Hash | ForEach-Object
        {
            If (!(Test-Path $_.Name))
            {
                $map = new-object -ComObject WScript.Network
                $map.MapNetworkDrive($_.Name, $_.Value, $true)
                Write-Host "Mapped That Stuff"
            }
            else
            {Write-Host ($Hash.Name) + ($Hash.Value)}
        }

How do I have to use foreach in this situation? Or is there a better way to solve this issue instead of a hashtable or a foreach loop?

To iterate over a [hashtable] you need to get an enumerator for it:

   $Hash.GetEnumerator() | ForEach-Object {
        If (!(Test-Path $_.Name))
        {
            $map = new-object -ComObject WScript.Network
            $map.MapNetworkDrive($_.Name, $_.Value, $true)
            Write-Host "Mapped That Stuff"
        }
        else
        {Write-Host ($_.Name) + ($_.Value)}
    }

I usually just use the Keys property of a hashtable to iterate over it. So your script would be:

$Hash = @{
    "h:" = "\\server\share";
    "i:" = "\\server\share";
    "j:" = "\\server\share";
    "k:" = "\\server\share";
    "p:" = "\\server\share";
    "z:" = "\\server\share";
    }
        $Hash.Keys | ForEach-Object
        {
            If (!(Test-Path $_))
            {
                $map = new-object -ComObject WScript.Network
                $map.MapNetworkDrive($_, $Hasj.$_, $true)
                Write-Host "Mapped That Stuff"
            }
            else
            {Write-Host ($_) + ($Hash.$_)}
        }

Actually, after looking at it I think I'd take a shorter route, use a Where statement to just find the drives that don't exist, and then map those drives:

$Hash = @{
    "h:" = "\\server\share";
    "i:" = "\\server\share";
    "j:" = "\\server\share";
    "k:" = "\\server\share";
    "p:" = "\\server\share";
    "z:" = "\\server\share";
    }

$Hash.Keys | Where{!(Test-Path $_)} | ForEach{ New-PSDrive -Name $_.trim(':') -PSProvider FileSystem -Root $Hash.$_ -Persist }

I used the New-PSDrive cmdlet there and the -Persist argument which then makes a standard Windows Mapped Drive that you can see and manage through Windows Explorer just like any other mapped drive. If you don't want that kind of mapping just remove the -Persist argument and it will then just be mapped for your script.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM