VMware Cloud Community
SCharchouf
Hot Shot
Hot Shot
Jump to solution

Get output of runing Script

I have a script that I will run it in production env.

My question is there any way to collect all output from the scipt is launched?

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Since you can redirect most streams when calling a .ps1 script (as I showed earlier), that script should be ok.

Just two remarks:

- if you are using PSv5 or higher, I would replace all Write-Host instances with Write-Information

- since Read-Host input is not echoed, I would avoid using that.

An alternative is to use the build-in prompt for mandatory parameters.

[CmdletBinding()]

Param(

    [Parameter(Mandatory=$true,

    HelpMessage="Enter a value")]

    [int]$Value

)

When running this, it will prompt with

prompt.png

That also allows you to run the script from another script or as a scheduled task.
You just the parameter along on the invocation of the script.

.\test.ps1 -Value 1


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

9 Replies
a_p_
Leadership
Leadership
Jump to solution

Please see whether Start-Transcript (Microsoft.PowerShell.Host) - PowerShell | Microsoft Docs is what you are looking for.

André

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

It is not clear to me if you want to capture output from a script that is already running or from a script that you will start (and can change)?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
SCharchouf
Hot Shot
Hot Shot
Jump to solution

not sure if what I will explain can clarify what I would like to capture,

the script will start and ask for vcenter FQDN, login,password, and it will do some stuff like changing advanced parametres...

once the script is finished all what was done should be collected in output file

something like this:

29.06.2018 16:52:53 INFO    Get script parameters K:\script\script.ps1

29.06.2018 16:52:53 INFO    Get credential: admin@lab.local

29.06.2018 16:52:53 INFO    Connect to vCenter server: vcenter1

29.06.2018 16:53:24 INFO    Connect to vcenter done

29.06.2018 16:53:24 INFO    ESXi Change

29.06.2018 16:53:41 INFO    ESX NAME: ESXi1

29.06.2018 16:53:42 ERROR    PARAMETER CHANGE FAILED: +details

29.06.2018 16:53:52 INFO    ESX NAME: ESXi2

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Start-Transcript will capture all output, provided you set some preference variables in the script.
Also note that since PSv5, the input entered on Read-Host is NOT echoed to the transcript file anymore.

Start-Transcript -Path .\transcript.log

$DebugPreference = 'Continue'

$VerbosePreference = 'Continue'

$InformationPreference = 'Continue'


$test = Read-Host

Invoke-Expression -Command 'cmd /c echo stdoutCMD'

Write-Output 'Stdout'

Write-Warning -Message 'Warning'

Write-Debug -Message 'Debug'

Write-Verbose -Message 'Verbose'

Write-Information -MessageData 'Info'

Write-Host 'Console'

Write-Error -Message 'Error'

throw 'Exception'


Stop-Transcript


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

SCharchouf
Hot Shot
Hot Shot
Jump to solution

Thank you LucD

below is the script that I have created, it will include other lines for Hardening ESXi nodes, like what I have made in this script it collect the info into logs file, my question is :

could you please check the same to confirm if it's a right way to continue working on thius script like the structure that I'm using?

is there any smarter way to have something in the script to collect all output session?

$StartTime = Get-Date

if (-not (Test-Path '.\Reports-ESXi')) { New-Item -Path '.\Reports-ESXi' -ItemType Directory -Force | Out-Null }

$reportHardening= ".\Reports-ESXi"

if (-not (Test-Path '.\Reports-LOGs')) { New-Item -Path '.\Reports-LOGs' -ItemType Directory -Force | Out-Null }

$reportLOGs= ".\Reports-LOGs"

$dateF = Get-Date -UFormat "%d-%b-%Y_%H-%M-%S"

$PathESXi = "$reportHardening\$dateF"

$PathLOGs = "$reportLOGs\$dateF"

$LogFile = "$PathLOGs\Start-Script.log"

$dateF | Out-File $LogFile -Encoding "UTF8" -Force

function Reports-Module-Check ($m) {

    # If module is imported say that and do nothing

    if (Get-Module | Where-Object {$_.Name -eq $m}) {

        write-host "Module $m "  -f Magenta -NoNewLine

       

        write-host "is already imported." -f Green

       "$(Get-date) Module $m is already imported" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

    } else {

        # If module is not imported, but available on disk then import

        Write-Warning "Module $m is NOT imported (must be installed before starting)."

       

        "$(Get-date) Module $m is NOT imported (must be installed before starting)" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

       

        if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) {

            Import-Module $m -Verbose

        } else {

            # If module is not imported, not available on disk, but is in online gallery then install and import

            if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) {

                Install-Module -Name $m -Force -Verbose -Scope CurrentUser

                Import-Module $m -Verbose

            } else {

                # If module is not imported, not available and not in online gallery then abort

                Write-Warning "Module $m not imported, not available and not in online gallery, exiting."

        "$(Get-date) Module $m not imported, not available and not in online gallery, exiting." | Out-File $LogFile  -Append -Encoding "UTF8" -Force

       

                EXIT 1

            }

        }

    }

}

Reports-Module-Check "CredentialManager"

Reports-Module-Check "VMware.PowerCLI"

function Reports-Folder-Check ($dir) {

    if(!(Test-Path -Path $report\$dir )){

        New-Item -ItemType directory -Path $report\$dir

        Write-Host "New Reports-ESXi folder created" -f Magenta

       

        "$(Get-date) New Reports-ESXi folder created" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

       

        New-Item -Path $report\$dir -Name $dateF -ItemType "directory"

        Write-Host "New Work folder created"   -f Magenta

       

        "$(Get-date) New Work folder created" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

       

    }

    else{

      Write-Host "Reports-ESXi Folder already exists" -f Green

     

      "$(Get-date) Reports-ESXi Folder already exists" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

     

      New-Item -Path $report\$dir -Name $dateF -ItemType "directory"

      Write-Host "New Work folder created"  -f Magenta

     

      "$(Get-date) New Work folder created" | Out-File $LogFile  -Append -Encoding "UTF8" -Force

     

    }   

}

Reports-Folder-Check "Reports-ESXi"

#################################

#   vSphere Targeting Variables #

################################# 

$vCenterList = Read-Host 'Enter vCenter FQDN or IP'

$username = Read-Host 'Enter The vCenter Username'

$password = Read-Host 'Enter The vCenter Password' -AsSecureString   

$vccredential = New-Object System.Management.Automation.PSCredential ($username, $password)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Since you can redirect most streams when calling a .ps1 script (as I showed earlier), that script should be ok.

Just two remarks:

- if you are using PSv5 or higher, I would replace all Write-Host instances with Write-Information

- since Read-Host input is not echoed, I would avoid using that.

An alternative is to use the build-in prompt for mandatory parameters.

[CmdletBinding()]

Param(

    [Parameter(Mandatory=$true,

    HelpMessage="Enter a value")]

    [int]$Value

)

When running this, it will prompt with

prompt.png

That also allows you to run the script from another script or as a scheduled task.
You just the parameter along on the invocation of the script.

.\test.ps1 -Value 1


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

SCharchouf
Hot Shot
Hot Shot
Jump to solution

Thanks LucD Smiley Happy

I got the first point to replace all Write-Host instances with Write-Information, unfortunately I'm totaly lost regarding the second point to avoid using Read-Host :smileyblush::smileyblush:

could you please assist me on this? as this is the first part of a long script that will be created and I prefere to devellop it in smart way and with good best practice

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

There are a couple of drawbacks with Read-Host as far as I'm concerned.

- the value you enter on a Read-Host prompt is not echoed to a Transcript file (since PSv5)

- Read-Host is intended for 'interactive' scripts. If you intend to use your script as a Scheduled Task or a background job (Start-Job), it is not too obvious to provide the replies to these Read-Host prompts.

The alternative is to replace those Read-Host lines with actual parameters to the script (Param line).

That way it is easy to provide values when running the script as a Scheduled Task or as a background job.

Even when you run your script interactively, you can still get prompted for a value if you define the parameter as Mandatory.

And you provide a meaningful prompt (after typing !? at the prompt) via the HelpMessage parameter on the param definition.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

SCharchouf
Hot Shot
Hot Shot
Jump to solution

Thanks for your help and clarification, for sure this script will be used interactively, never as a scheduled task or a background task Smiley Happy

Thanks again for your help Smiley Happy

Reply
0 Kudos