locked
add/set-content not working remotely as expected RRS feed

  • Question

  • Hi,

    Im running following command:

    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock {param($block,$hostsource)set-content -path c:\temp\dtv8\dtsetupsrc.ini -value $block;Add-Content -Path c:\temp\dtv8\dtsetupsrc.ini -value $hostsource.key} -ArgumentList $block,$hostsource

    but only the first part Set-content is executed. No error message, no nothing. But the add-content does not add the value to the file.

    If I run the commands separately it works well.

    The command works well locally at one line.

    what am I doing wrong? I got both parameters mentioned and in arg list.

    thx


    --------------------- Leos

    Wednesday, November 8, 2017 12:25 PM

Answers

  • This works as expected.

    $block = 'line 1'
    $hostsource = [pscustomobject]@{Name='Test';key='line 2'}
    $sb = {
        param (
            $block,
            $hostsource
        )
        set-content -path dtsetupsrc.ini -value $block
        Add-Content -Path dtsetupsrc.ini -value $hostsource.key 
    }
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $sb -ArgumentList $block, $hostsource
    


    \_(ツ)_/

    • Marked as answer by Leoš Marek Wednesday, November 8, 2017 1:31 PM
    Wednesday, November 8, 2017 12:48 PM

All replies

  • This works as expected.

    $block = 'line 1'
    $hostsource = [pscustomobject]@{Name='Test';key='line 2'}
    $sb = {
        param (
            $block,
            $hostsource
        )
        set-content -path dtsetupsrc.ini -value $block
        Add-Content -Path dtsetupsrc.ini -value $hostsource.key 
    }
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $sb -ArgumentList $block, $hostsource
    


    \_(ツ)_/

    • Marked as answer by Leoš Marek Wednesday, November 8, 2017 1:31 PM
    Wednesday, November 8, 2017 12:48 PM
  • whats the difference technical wise? :)

    --------------------- Leos

    Wednesday, November 8, 2017 1:05 PM
  • The difference is that properly formatted code makes mistakes easier to see.


    \_(ツ)_/

    Wednesday, November 8, 2017 1:15 PM
  • thx :)

    --------------------- Leos

    Wednesday, November 8, 2017 1:31 PM
  • Im running into another issue with this.

    I have 2 objects in $hostsource

    Name         Key                    
    ----         ---                    
    czmbomiitst1 DTACTIVATIONCODE=123456
    czmbomiitst5 DTACTIVATIONCODE=654321


    when I use this:

    $invokeSource = {
        param (
        $blocksource,
        $hostsource
        )
        New-Item -ItemType File -Path c:\temp -Name DT.ini
        Set-Content -Path C:\temp\DT.ini -value $blocksource
        Add-Content -Path C:\temp\DT.ini -Value $hostsource.key
    }
    
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $invokeSource -ArgumentList $blocksource,$hostsource

    I end up like this

    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    DTACTIVATIONCODE=123456
    DTACTIVATIONCODE=654321

    File on first PC does not have the .key value at all, second PC has it twice.

    Do I need to use for-each loop here to accomplish the mission?

    thx


    --------------------- Leos

    Wednesday, November 8, 2017 6:44 PM
  • Your source is not a CSV.


    \_(ツ)_/

    Wednesday, November 8, 2017 6:51 PM
  • not getting the point. what should be the difference?

    if I import the $hostsource from CSV the result is the same.


    --------------------- Leos

    Wednesday, November 8, 2017 7:03 PM
  • Name is czmbomiits

    Key is 1 DTACTIVATIONCODE=123456

    Keys usually cannot have spaces or "=" signs.

    An INI or config file is a set of name/value pairs.  The "name" aprt cannot have spaces and must be followed by an equal sign and a string.

    The CSV is delimited with a semi-colon. The rest is how PowerShell works.

    Perhaps your file has nulls or other unprintable characters.


    \_(ツ)_/


    • Edited by jrv Wednesday, November 8, 2017 8:00 PM
    Wednesday, November 8, 2017 7:56 PM
  • edit:

    its just bad formatting, this is the csv

    name,key
    czmbomiitst1,DTACTIVATIONCODE=132456
    czmbomiitst5,DTACTIVATIONCODE=645321

    you can see that on czmbomiitst1 I got file created with content

    [Config] DTSETUPTYPE=DTSO DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take" QMEMORYBUFFERMAX=1024 DISKQUEUEFOLDER="C:\DTQueue" DISKQUEUEMAXSIZE=UNLIMITED DISKFREESPACEMIN=4096 PORT=6320 WINFW_CONFIG_OPTION=NONE LICENSE_ACTIVATION_OPTION=0

    on czmbomiitst5 with

    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    DTACTIVATIONCODE=123456
    DTACTIVATIONCODE=654321


    --------------------- Leos


    • Edited by Leoš Marek Wednesday, November 8, 2017 8:00 PM
    Wednesday, November 8, 2017 7:58 PM
  • If host source is a CSV then it must be enumerated.


    \_(ツ)_/

    Wednesday, November 8, 2017 8:00 PM
  • CSV

    name,key
    czmbomiitst1,132456
    czmbomiitst2,6545646
    czmbomiitst5,645321


    code:

    $hostsource = Import-Csv D:\temp\dt.csv

    $blockSource = '
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0'

    $invokeSource = { param ( $blocksource, $hostsource ) New-Item -ItemType File -Path c:\temp -Name DT.ini Set-Content -Path C:\temp\DT.ini -value $blocksource Add-Content -Path C:\temp\DT.ini -Value $hostsource.key } Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $invokeSource -ArgumentList $blocksource,$hostsource

    Result:

    1 file with all 3 values:

    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    132456
    6545646
    645321

    Other 2 files have only the 

    $blocksource

    try it .)


    --------------------- Leos

    Wednesday, November 8, 2017 8:04 PM
  • Add-Content -PathC:\temp\DT.ini -Value"$($hostsource.Name)=$($hostsource.key)"

    \_(ツ)_/

    Wednesday, November 8, 2017 8:08 PM
  • Doing so remotely ends up with only = added to the file, locally.

    The assignment expression is not valid. The input to an assignment operator must be an o
    bject that is able to accept assignments, such as a variable or a property.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : InvalidLeftHandSide

    I try google later on .)


    --------------------- Leos

    Thursday, November 9, 2017 4:25 AM
  • You have to build the file and copy it as a whole file.

    $blockSource = @'
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    '@
    
    $blockSource += Import-Csv D:\temp\dt.csv | ForEach-Object{'{0}={1}' -f $_.Name,$_.Key}
    
    
    
    $invokeSource = {
        param (
            $blocksource
        )
        $blocksource | Out-File C:\temp\DT.ini
    }
    
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $invokeSource -ArgumentList $blocksource
    

    If this isn't what you are asking then you will have to find a way to describe what you want that accurately describes what you are trying to do.


    \_(ツ)_/

    Thursday, November 9, 2017 4:33 AM
  • What Im trying to do is to generate this file for a software installation, each server has its unique license key.

    that are the values I have in $hostsource.Name and $hostsource.Key.

    My intention was to build the file on the remote computer, not local and then copy it.

    I was trying to understand why using 

    $invokeSource = {
        param (
        $blocksource,
        $hostsource
        )
        New-Item -ItemType File -Path c:\temp -Name DT.ini
        Set-Content -Path C:\temp\DT.ini -value $blocksource
        Add-Content -Path C:\temp\DT.ini -Value $hostsource.key
    }
    
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $invokeSource -ArgumentList $blocksource,$hostsource

    Ends up with one computer having all the keys inside its file.

    I can easily do what I need using foreach block and enumerate the $hostsources one by one.

    :)


    --------------------- Leos

    Thursday, November 9, 2017 4:36 AM
  • Sorry but I cannot guess any longer what you are trying to do.  You will need to find some one to explain your problem.  I suggest strting by learning the basics of PowerShell.  That will help you to understand how to ask a good technical question.


    \_(ツ)_/

    Thursday, November 9, 2017 4:46 AM
  • its sometimes funny with you man... You keep posting with me since yesterday giving advice and now you say I didnt ask properly :))

    I believe I have explained the situation pretty well here:

    CSV
    name,key
    czmbomiitst1,132456
    czmbomiitst2,6545646
    czmbomiitst5,645321
    
    code:
    
    $hostsource = Import-Csv D:\temp\dt.csv
    $blockSource = '
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0'
    
    $invokeSource = {
        param (
        $blocksource,
        $hostsource
        )
        New-Item -ItemType File -Path c:\temp -Name DT.ini
        Set-Content -Path C:\temp\DT.ini -value $blocksource
        Add-Content -Path C:\temp\DT.ini -Value $hostsource.key
    }
    
    Invoke-Command -ComputerName $hostsource.Name -ScriptBlock $invokeSource -ArgumentList $blocksource,$hostsource
    
    Result:
    1 file with all 3 values:
    
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    132456
    6545646
    645321
    
    Other 2 files have only the 
    $blocksource
    try it .)

    So to sum up:

    - I have a csv file with computername and license key that is imported to $hostsource

    - On each of the computernames I need to build a file that has fixed part ($blocksource) and flexible part - value of $hostsource.key

    - Doing it like above ends up with 1 computer having all 3 keys, other 2 computers have only the fixed part inside the file

    what is not clear in this description?

    Doing this:

    $invokeini = {
        param (
        $blocksource,
        $one
        )
        New-Item -ItemType File -Path c:\temp -Name DT.ini
        Set-Content -Path C:\temp\DT.ini -value $blocksource
        Add-Content -Path C:\temp\DT.ini -Value $one.key
    }
    foreach ($one in $hostsource) {
        Invoke-Command -ComputerName $one.name -ScriptBlock $invokeini -ArgumentList $blockSource,$one
    }
    is doing what I need


    --------------------- Leos

    Thursday, November 9, 2017 4:56 AM
  • That does not explain what you are trying to do.  You are missing some important information.

    Are you tying to add one line to the file for each computer? 

    You may have what you want in your head but your explanation is quite odd.

    First you post ma script with one computer and say that doesn't work then you post a script with a list of computers.  That is quite confusing.

    What is the desired results?  Your key is one number.  I posted a method to add that and you complained.

    If you add one line to each computer with this then:

    I will guess again what it is you are trying to do.

    $invokeSource = {
        param (
            $line
        )
        $blockSource = @"
    [Config]
    DTSETUPTYPE=DTSO
    DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take"
    QMEMORYBUFFERMAX=1024
    DISKQUEUEFOLDER="C:\DTQueue"
    DISKQUEUEMAXSIZE=UNLIMITED
    DISKFREESPACEMIN=4096
    PORT=6320
    WINFW_CONFIG_OPTION=NONE
    LICENSE_ACTIVATION_OPTION=0
    `n
    "@ + $line
        $blocksource | Out-File C:\temp\DT.ini
    }
    
    Import-Csv D:\temp\dt.csv |
        ForEach-Object{
            Invoke-Command -ComputerName $_.Name -ScriptBlock $invokeSource -ArgumentList $_.Key
        }
    


    \_(ツ)_/

    Thursday, November 9, 2017 5:09 AM
  • Yes thats it man. Same thing as with this:

    $invokeini = {
        param (
        $blocksource,
        $one
        )
        New-Item -ItemType File -Path c:\temp -Name DT.ini
        Set-Content -Path C:\temp\DT.ini -value $blocksource
        Add-Content -Path C:\temp\DT.ini -Value $one.key
    }
    foreach ($one in $hostsource) {
        Invoke-Command -ComputerName $one.name -ScriptBlock $invokeini -ArgumentList $blockSource,$one
    }

    OK I try to explain next time even better.

    thx


    --------------------- Leos

    Thursday, November 9, 2017 5:27 AM