0

I have a small powershell script that is meant to get column ServerName from a remote SQL database called, Hal0Test > from table, ServerList. However, I can not figure out this Powershell Error.

Newest Code:

Write-Output " `n Start of Hal0 `n";

$connectionString = "Server=QAUTILITYDB01;Database=Hal0Test;Integrated Security=True;"
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()

$ServerArray = [System.Collections.ArrayList]@()
$query = "SELECT ServerName FROM ServerList"
$command.CommandText = $query
$ServerNames = $command.ExecuteReader()

$table = new-object “System.Data.DataTable”
$table.Load($ServerNames)

$ServerArray = $table | select -Expand ServerName

$ServerArray | ForEach-Object {
    # $Server returns each server name
    $os    = Get-WmiObject -Class Win32_OperatingSystem -Computer $_
    $disks = Get-WmiObject -Class Win32_LogicalDisk -Computer $_ |
             Where-Object {$_.DriveType -eq 3} |
             ForEach-Object {
                 '{0} {1:D} MB Free/{2:D} MB Used' -f $_.DeviceID,
                     [int]($_.FreeSpace/1MB), [int]($_.Size/1MB)
             }

    New-Object -Type PSCustomObject -Property @{
      'FQDN'            = $_
      'ServerName'      = $os.PSComputerName
      'OperatingSystem' = $os.Caption
      'Disks'           = $disks -join ' | '
    }
    $command.CommandText = "UPDATE ServerList SET FQDN = '$_', OS = '$os.Caption' WHERE ServerName = '$os.PSComputerName';"
    $result = $command.ExecuteNonQuery()  
} | Export-Csv 'C:\Users\king\Desktop\HalO\output.csv' -Delimiter '|' -NoType
Write-Output "`n End of Hal0";

SQL Table:

enter image description here

2 Answers 2

3

You changed my ForEach-Object loop to a foreach loop. If you want to use the latter you need to change the current object variable $_ to your loop variable $Server:

foreach ($Server in $ServerArray) {
  $os    = Get-WmiObject -Class Win32_OperatingSystem -Computer $Server
  $disks = Get-WmiObject -Class Win32_LogicalDisk -Computer $Server | ...

  ...
}

otherwise you need to change the loop back to a ForEach-Object loop:

$ServerArray | ForEach-Object {
  $os    = Get-WmiObject -Class Win32_OperatingSystem -Computer $_
  $disks = Get-WmiObject -Class Win32_LogicalDisk -Computer $_ | ...

  ...
}

Also, there's no pipe between } and Export-Csv:

    $result = $command.ExecuteNonQuery()  
} Export-Csv 'C:\Users\mdaraghmeh\Desktop\HalO\output.csv' -Delimiter '|' -NoType
 ^
here

And even if there were would the foreach loop still be unable to feed its output into the pipeline. If you want to use foreach with a pipeline you must assign the output to a variable:

$output = foreach ($Server in $ServerArray) { ... }
$output | Export-Csv ...

or run it in an expression:

(foreach ($Server in $ServerArray) { ... }) | Export-Csv ...

For direct pipeline processing you need a ForEach-Object loop:

$ServerArray | ForEach-Object { ... } | Export-Csv ...
Sign up to request clarification or add additional context in comments.

9 Comments

For the direct pipeline I do not understand, I have editted my code to reflect your advice.
So add a "|" between } <HERE> Export-Csv and for the direct pipeline what goes into the loop {...}? What I am misssing in my new code?
The ellipsis (...) is just a placeholder for the code from the body of your loop. Why do you think you need to change anything there?
I do not know what to make the loop do lol? Honestly I am very confused and would love the help. For this is first project like this and I would like to do more to get the hang of Powershell/SQL
What's wrong with leaving the code inside the loop as it is? Does something not work as expected? Do you get an error?
|
2

You need to use a [datatable] to store the result of your select:

$connectionString = "Server=QAUTILITYDB01;Database=Hal0Test;Integrated Security=True;"
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()

$ServerArray = [System.Collections.ArrayList]@()
$query = "SELECT ServerName FROM ServerList"
$command.CommandText = $query
$ServerNames = $command.ExecuteReader()

$table = new-object "System.Data.DataTable"
$table.Load($ServerNames)

Now $table has your servers name list.

3 Comments

Thank you @CB. but now I am gettig a weird error as well as an InputObject command in the console.
@TheAce the result of your select is in $table. You don't need any more $servernames.read() ... you follow me? Need to change foreach($Server in $ServerArray) in foreach($Server in $table) and go
would you mind editting your answer with the full code for I am not completetly getting what you are saying. Sorry about that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.