Move a line of text from one txt file to another

This topic contains 9 replies, has 3 voices, and was last updated by  Don Jones 2 months, 1 week ago.

  • Author
  • #95949

    Terry V

    I have 2 text files: 1 for online computers, 1 for offline computers. These files were generated using powershell by pinging computers in a specific OU and writing the pingable computers to Onlinecomps.txt and writing the un-pingable computers to Offlinecomps.txt.

    I am creating a new Local Admin account on all the computers in the domain. Some computers are not online at all times (laptops, tablets etc).

    The part of the script to create the account on an online computer already works. But from this point on, I only want to iterate through the offlinecomps.txt, ping them and if any of them is online; create the local admin account, take the computername out of the file and append it to the onlinecomps.txt file.

    I would run this script manually, several times a day until all computers have the new Local Admin account. (Then I will look at disabling "The" Administrator account).

    I know I can get the computer names from the get-content and using a foreach, but I can't seem to find a way to remove it from one file and append it to another.

    $x = Get-Content c:\temp\offlinecomps.txt
    Foreach($comp in $x) {
    $ping=Test-Connection $ -count 1 -quiet
    If ($Ping) {
    Create the account script — this part of my script already works as it should.
    Remove that line from offlinecomps.txt file
    Add that computername to the onlinecomps.txt so that it does not get tested the next time the script is run...

    Any help would be appreciated.

    Thank You

  • #95958

    Don Jones

    You can't remove a line from a file. You need to read in the entire file, and write out, to a new file, the lines you want to keep. PowerShell's text file manipulation just isn't complex enough to support search-and-replace type activities.

    So, read in file A, write out file B, delete file A, rename B to A.

    Appending is easy. Use Add-Content or Out-File with the -Append parameter.

    • #96062

      Terry V

      That's Awesome
      Thank you for the concept of how it needs to be done.


    • #96114

      Terry V

      1. I need to preserve values in the onlinecomps.txt and add new compnames that are currently pingable.
      2. I need to remove those currently pingable compnames from offlinecomps.txt and save the file with the same name.
      3. The two text files are created by another script that simply tries to ping the computer from AD. And based on the ping results
      the computer names are put into the appropriate file.



      Currently pingable computers – Six, Nine, Ten

      Here's what Im doing:

      $txt1=get-content D:\Tmp\onlinecomps.txt
      $txt2=get-content D:\tmp\offlinecomps.txt
      $Lookup = @{
          "=>" = "Present in File2"
          "< =" = "Present in File1"
          "==" = "Present in both files"
      $Vals=Compare-Object -ReferenceObject $txt1 -DifferenceObject $txt2 -IncludeEqual | Select @{Name="String";Expression={$_.InputObject}},@{Name="Presence";Expression={$Lookup[$_.SideIndicator]}}
      foreach($L in $Vals) {If($L.Presence -eq "Present in both Files") { Add-Content -Path D:\Tmp\onlinecomps.txt -Value $L.String
      $A += $L.String
      For ($b -eq 0;$b -le $A.count;$b ++) {
      $offline =$txt2 | Where {$A -notmatch $A[$b] } | Set-Content D:\Tmp\offlinecomps.txt}  # I'm out to lunch on this line....

      So, $A collects the currently pingable computers (it collects the right values)
      $offline contains all comps listed in offlinecomps.txt except those that don't match any of the values in $A — so that I will now have all currently offline computers for the next time I run my script.
      It all seems to work except the rebuilding of the offlinecomps.txt

      Any suggestions?

      Thank You

  • #96117

    Don Jones

    The logic seems overly complex for me.

    ForEach ($line in (Get-Content offline.txt)) {
      if ( (Test-Computer -Comp $line -Quiet) ) {
        $line | Out-File online.txt -Append
      } else {
        $line | Out-File newoffline.txt -Append
    Remove-Item offline.txt
    Rename-Item newoffline.txt offline.txt

    No? Or am I massively missing something? I guess I don't understand the need to compare files, nor all the array management.

    • #96119

      Terry V

      It may seem over complex to you because I am a noob 🙂
      Thanks Don
      I'll try the new "simpler" logic 🙂


  • #96122

    Don Jones

    Sorry, I did miss the bit about the other script doing the pinging. That seems unnecessary. But whatever, if that's what you've got. I'm having trouble following the need, then.

    1. I need to preserve values in the onlinecomps.txt and add new compnames that are currently pingable.
    How do you know which computer names are "currently pingable?" If all computers in onlinecomps.txt respond to a ping, then by definition everything in onlinecomps.txt are pingable, right?

    2. I need to remove those currently pingable compnames from offlinecomps.txt and save the file with the same name.
    How do you know which computers in offlinecomps.txt are pingable?

    Like, are you saying it's possible for both files to contain a given computer name, and if so, then the computer is pingable and should be removed from offlinecomps.txt? If this other script is populating these files, why isn't it just updating both files correctly?

    • #96183

      Terry V

      Hi Don
      I Apologize for being unclear:
      My other script searches an OU and pulls out computer names.
      It then pings the computer (by name); if the computer pings successfully, it gets put into an array with it's model. If the computer does not ping successfully, it is written to the offlinecomps.txt file (so that I can monitor which computers have and which have not received a new LocalAdmin Account. Not all computers are on the network all the time – some are in the field etc.

      Now these files have been created, so I now only need to test ping the "offline" computers to see if any of them are now online.
      If they are online, the script will create a new LocalAdmin account on it/them. The computername will be taken out of the "offline" computers text file and placed in the "online" computers text file (so that it does not get tested the next time).

      $userName = 'newAdmin'
      $password = ConvertTo-SecureString -String '123456789' -AsPlainText -Force
      $group = 'Administrators'
      $computers=Get-ADComputer -filter * -SearchBase "OU=Test OU,OU=Computers,OU=AnotherOU,DC=Domain,DC=local"
      foreach ($comp in $Computers) 
      Invoke-Command -ComputerName $comp.Name -ArgumentList $userName, $password, $group -ScriptBlock {
          New-LocalUser -Name $args[0] -FullName 'Local Admin' -Description 'Local Admin Account' -Password $args[1] -PasswordNeverExpires -AccountNeverExpires -UserMayNotChangePassword
          Add-LocalGroupMember -Group $args[2] -Member $args[0]

      Once all computers have been successfully processed (they have all received the new LocalAdmin Account), I can then inventory all computers for each model, simply by querying the "onlinecomps.txt" file.

      So my scripting is dual purposed. It gathers the computer names and models and it ensures that all computers in the domain get the new Admin Account.

      The reason I am not creating a GPO to create the new admin account is because I do not want to have a file on the network with a clear password. So, I will run this script from my own desktop and when its all done, I will place it in a protected place on the network. Seems MS has recently disallowed a computername to be considered a user for authentication, So any authenticated user would have access to view the script (not that most would know how to find it or what to do with it).

      I hope I have explained my scenario clearly

      Thank you

  • #96152

    Simon B

    Why not just use group policy to create the local admin account ??

  • #96186

    Don Jones

    OK. So, my previous short example should at least give you the logic you need. Read in the offline names, ping and do whatever with them. If they ping, append them to online. If they don't, write them to a new offline file. At the end, delete the original offline file and rename the new one.

    I'll second the GPO comment, though. Much more reliable way to manage privileged accounts.

You must be logged in to reply to this topic.