Get-Content and foreach in two files

前端 未结 1 1251
傲寒
傲寒 2021-01-26 07:23

I have two files. The first with contains hostnames (Computers.txt) and the second one contains SID (SID.txt). I want to use Get-Content and foreach to

相关标签:
1条回答
  • 2021-01-26 08:17
    • Using a foreach-loop doesn't give you the current linenumber so it's impossible to get the same line from the SIDs-list. You should use a while- or for-loop to create an index that increments by one for each run so you know the "current line".

    • There's no HKEY_USERS: PSDrive. You need to access it using the Registry-provider, like Registry::HKEY_USERS\

    • Variables in your local scope (ex. $currentsid) aren't accessible inside the Invoke-Command-scriptblock since it's executed on the remote computer. You can pass it in using -ArgumentList $yourlocalvariable and call it with $args[0] (or put param ($sid) at the beginning of the scriptblock). With PS 3.0+ this is much simpler as you can use the using-scope ($using:currentsid) in your script.

    Example:

    $Computers = Get-Content D:\Downloads\computers.txt
    $SIDs = Get-Content D:\Downloads\SID.txt
    
    #Runs one time for each value in computers and sets a variable $i to the current index (linenumer-1 since arrays start at index 0)
    for($i=0; $i -lt $Computers.Length; $i++) {
        #Get computer on line i
        $currentpc = $Computers[$i]
        #Get sid on line i
        $currentsid = $SIDs[$i]
    
        #Invoke remote command and pass in currentsid
        Invoke-Command -ComputerName $currentpc -ScriptBlock { param($sid) New-Item "REGISTRY::HKEY_USERS\$sid" -Name "SomeKeyName" } -ArgumentList $curentsid
    
        #PS3.0+ with using-scope:
        #Invoke-Command -ComputerName $currentpc -ScriptBlock { New-Item "REGISTRY::HKEY_USERS\$using:currentsid" -Name "SomeKeyName" }
    }
    

    One-liner:

    0..($Computers.Length-1) | ForEach-Object { Invoke-Command -ComputerName $Computers[$_] -ScriptBlock { param($sid) New-Item REGISTRY::HKEY_USERS\$sid -Name "SomeKeyName" } -ArgumentList $SIDs[$_] }
    

    On a side-note: Using two files with matching line numbers is a bad idea. What if comptuers has more lines than SIDs? You should be using a CSV-file that maps computer and SID. Ex..

    input.csv:

    Computer,SID
    PC1,S-1-5-21-123123-123213
    PC2,S-1-5-21-123123-123214
    PC3,S-1-5-21-123123-123215
    

    This is safer, easier to maintain and you can use it like this:

    Import-Csv input.csv | ForEach-Object { 
        Invoke-Command -ComputerName $_.Computer -ScriptBlock { param($sid) New-Item REGISTRY::HKEY_USERS\$sid -Name "SomeKeyName" } -ArgumentList $_.SID
    }
    
    0 讨论(0)
提交回复
热议问题