Powershell - Get total jobs printed from list of printers - powershell

Trying to get total jobs printed.
It works fine for one printer:
cls
$WebResponse = Invoke-WebRequest "10.240.16.156/server/JOBLOG.htm"
$Total = $WebResponse.AllElements | Select innerText | Select -Index '12'
$Total
Output:
innerText
---------
Total Jobs Printed:737
But I need to get that information from five hundred printers, that IP's I have in .csv file:
"PortName"
"10.240.8.27"
"10.240.9.87"
"10.240.19.81"
...
Tried to import IP from CSV, but it only uses last IP from .csv and cannot build a valid url:
cls
$Printers = Import-Csv -Path C:\path\to\csv\_printers.csv
$Url = "http://$PortName/server/JOBLOG.htm"
$WebResponse = ForEach ($PortName in $Printers) {Invoke-WebRequest $Url}
$Total = $WebResponse.AllElements | Select innerText | Select -Index '12'
ForEach ($PortName in $Printers) {
$Total
}
Output:
Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert value "http://#{PortName=10.240.11.86}/server/JOBLOG.htm" to type "System.Uri". Error: "Invalid URI: The hostname could not
be parsed."
At line:4 char:68
+ ... bResponse = ForEach ($PortName in $Printers) {Invoke-WebRequest $Url}
+ ~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Any help?
Thanks

I'm guessing you're looking for something like this:
Import-Csv -Path C:\path\to\csv\_printers.csv | ForEach-Object {
$Url = "http://{0}/server/JOBLOG.htm" -f $_.PortName
[pscustomobject]#{
URL = $Url
Response = (Invoke-WebRequest $Url).AllElements.InnerText[12]
}
}
The error message is actually showing you the object being converted to a string (#{PortName=10.240.11.86}):
.. Cannot convert value "http://#{PortName=10.240.11.86}/server/JOBLOG.htm" ..
You need to expand the PortName property from your object to get the value (only the IP), hence the use of $_.PortName in my example.

Related

Wait-Task outputs an error when deploying VMs from a .csv file

I wrote a GUI script that clones VMs from a template and gives them a static IP address that they get from a .csv file.
Everything seems to work fine except for an error I'm getting. The clone completes successfully anyway, but I'm not sure how to fix the error or if I even should.
function StartClone {
$VM_List = Import-Csv $csvTB.Text
$numClones = [int]((Get-Content $csvTB.Text).Length)
$vmh = Get-VMHost
$NewParameters = #{
# Name = ''
Template = $TemplateMenu.Text
Datastore = $DatastoreMenu.Text
DiskStorageFormat = 'Thin'
Location = $FolderCB.Text
OSCustomizationSpec = $CustomizationCB.Text
VMHost = Get-Random -InputObject $vmh
Server = $VCenterTB.Text
RunAsync = $true
}
$SetParameters = #{
NumCpu = $CPU_TB.Text
MemoryGB = $RAM_TB.Text
Notes = $NotesTB.Text
Confirm = $false
}
$taskList = if ($NumClones -gt 0) {
# foreach ($item in (Import-Csv $csvTB.Text))
$VM_List | ForEach-Object {
$NewParameters['Name'] = "$($_.Hostname)"
Get-OSCustomizationSpec -name $CustomizationCB.Text | Get-OSCustomizationNICMapping | Set-OSCustomizationNICMapping -IPMode UseStaticIP -IPAddress "$($_.IP)" -SubNetMask "$($_.Subnet)" -DefaultGateway "$($_.Gateway)" -Dns ""
New-VM #NewParameters
}
}
$newVM = $taskList | Wait-Task -ErrorAction SilentlyContinue
$newVM | Set-VM #SetParameters
$newVM | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $VLAN_CB.Text -Confirm:$false
if ($StartVM_CB.Checked -eq $true) {$newVM | Start-VM }
}
The error I get is related to the Wait-Task command which I have to use to wait for the VMs to actually be done cloning.
Wait-Task : The input object cannot be bound to any parameters for the command either because
the command does not take pipeline input or the input and its properties do not match any of
the parameters that take pipeline input.
At line:465 char:26
+ $newVM = $taskList | Wait-Task
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (UseStaticIP:192.168.1.1:PSObject) [Wait-Tas k], ParameterBindingException + FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.Common.Commands.Cmdlets. WaitTask
The error repeats for each VM in my .csv file, so if I have 4 VMs that I want to deploy, it will pop up 4 times. As the error suggests, it's related to the fact I'm looping over the .csv file and creating a new VM with with iteration, but like I said, everything completes without issues and the VMs are working.
Any input on this would be great. Thanks.
New-VM returns a VirtualMachineImpl object, and Wait-Task has nothing to do it...
If you add the -RunAsync parameter to New-VM it will return a TaskImpl object, then you can pipe the results to the Wait-Task cmdlet.

Is there a reason my Powershell script is now returning null-value expression errors?

As the title suggests, I have a script that I've been running daily to parse tables from a web page and export those to a csv. A few days ago though, I realized the script has been returning the following errors:
You cannot call a method on a null-valued expression. At C:\Users\Luke\DailyStats\NHLStats.ps1:16 char:1
+ $headers = $rows.item(1).children | select -ExpandProperty InnerText
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull Cannot index into a null array. At C:\Users\Luke\DailyStats\NHLStats.ps1:23 char:14
+ $headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray Cannot index into a null array. At C:\Users\Luke\DailyStats\NHLStats.ps1:23 char:33
+ $headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
I don't get why all of a sudden it randomly stopped working. Any and all help is greatly appreciated.
My script:
$url = "https://www.hockey-reference.com/leagues/NHL_2020.html"
#getting the data
$data = Invoke-WebRequest $url
#grab the third table
$table = $data.ParsedHtml.getElementsByTagName("table") | Select -skip 2 | Select -First 1
#get the rows of the Team Statistics table
$rows = $table.rows
#get table headers
$headers = $rows.item(1).children | select -ExpandProperty InnerText
#$headers = $headers | % { if ($_ -eq "GF") { "GFPG" } else { $_ }}
#count the number of rows
$NumOfRows = $rows | Measure-Object
#Manually injecting TEAM header and replace any headers you want to change
$headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
#enumerate the remaining rows (we need to skip the header row) and create a custom object
$allData = #{}
$out = for ($i=2;$i -lt $NumofRows.Count;$i++) {
#define an empty hashtable
$objHash=[ordered]#{}
#getting the child rows
$rowdata = $rows.item($i).children | select -ExpandProperty InnerText
for ($j=0;$j -lt $headers.count;$j++) {
#add each row of data to the hash table using the correlated table header value
$objHash[$headers[$j]] = $rowdata[$j]
}
#turn the hashtable into a custom object
[pscustomobject]$objHash
$allData.Add($i, $objHash)
}
$out | Select TEAM,AvAge,GP,W,L,OL,PTS,PTS%,GF,GA,SOW,SOL,SRS,SOS,TG/G,EVGF,EVGA,PP,PPO,PP%,PPA,PPOA,PK%,SH,SHA,PIM/G,oPIM/G,S,S%,SA,SV%,SO -SkipLast 1 | Export-Csv -Path "C:\Users\Luke\DailyStats\$((Get-Date).ToString("'NHL Stats' yyyy-MM-dd")).csv" -NoTypeInformation
Looks like your $table variable is returning null. When running that |select -skip 2 | select -first 1, it isn't returning any data to the $table variable.
This seems to be related to the -skip 2 selection.
When running just the portion of the $table = $data.ParsedHtml...
It only returns two objects.
So possibly you need to update your selection to properly retrieve the table that you want?
I am only seeing the 'standings EAS' and 'standings WES' tables being pulled.

List all azure resources with tagnames and tagvalues using PowerShell

I am trying to fetch OperatingHours tag details for all the Azure VirtualMachines and Azure SqlDatabases.
Following are the possibility for appID in a resource and the values I need to print in output correspondingly:
If OperatingHours tag itself is not present in any resource then display "Tag not present"
if OperatingHours tag is present but contains null or empty string then display "NULL/EMPTY"
if OperatingHours tag is present with any other value then display that value.
Do I need to take care of option (2) separately or is it like printing any normal value of the OperatingHours.
After long efforts I have created following script:
$ErrorOccured = $false
$resources = Get-AzureRmResource |
Where-Object {($_.ResourceType -eq "Microsoft.Compute/virtualMachines") -or ($_.ResourceType -eq "Microsoft.Sql/servers/databases")} |
foreach {
new-object psobject -Property #{
ResourceName = $_.ResourceName;
ResourceType = $_.ResourceType;
OperatingHours= try {
$ErrorActionPreference = 'SilentlyContinue';
($_ | select -expand Tags).OperatingHours; }
catch {
$ErrorOccured = $true ; }
if ($ErrorOccured)
{ "Tag not present" }
else {
($_ | select -expand Tags).OperatingHours;
$ErrorOccured = $false };}
}
$resources | Format-Table
When running this script, I am receiving following error:
At line:13 char:58
+ }
+ ~
The hash literal was incomplete.
At line:20 char:2
+ }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : IncompleteHashLiteral
If I replace the OperatingHours statement with following code then the script is running with success. But in doing so, I am not able to satisfy the option (1) mentioned above.
Operating Hours = if (!($_ | select -expand Tags).OperatingHours)
{"Tag not present"}
else {($_ | select -expand Tags).OperatingHours} ;
Please advise me on how to correct this and get the required output.
Thanks
After alot of hit and trial and rigorous testing, I found what I was looking for:
OperatingHours = if ( ($_ | select -expand Tags).OperatingHours -ieq $null )
{"TAG NOT PRESENT"}
elseif ( ($_ | select -expand Tags).OperatingHours -ieq '')
{"NULL/EMPTY"}
else
{($_ | select -expand Tags).OperatingHours } ;
I replaced the OperatingHours statement in original script to above.
The solution looks easy and after finding it I was like how could I miss that earlier, but that's what learning process is all about, right ?

Errors in listing AD groups for AD PCs

I am writing a script for work and trying to determine why my code is showing errors. I am new to this coding and want to understand what is wrong.
The errors I get are from the tag .... PC listings in my .txt file.
Ex: Get-Content : Cannot find path 'F:\tag 77909' because it does not exist.
My confusion is that when I write-host after the .Replace code it prints correctly
Ex:You cannot call a method on a null-valued expression. + $Notags =$PC.Replace <<<< ("tag ", "PC")
+ CategoryInfo : InvalidOperation: (Replace:String) [], RuntimeEx
ception
+ FullyQualifiedErrorId : InvokeMethodOnNull
Last error I get is that it only prints out the last PC.... ID in my .txt file listing??? I am unsure why given I have a foreach loop
**MY CODE SO FAR:**
Import-Module activedirectory
$compImports = Get-Content "C:\Temp\temp\input.txt"
$groupExport = "C:\temp\temp\output.txt"
Clear-Content $groupExport
$Header = "PC Name" + "|" + "Group Name" + "|" + "Group Description"
#Write header
$Header | Out-File $groupExport -Append
#get PC tag listing
$PCs = Get-Content $compImports
#For loop to change all "tag " to "PC"
foreach($PC in $PCS)
{
$Notags =$PC.Replace("tag ", "PC")
}
#loop to get information and print it out
foreach ($Notag in $Notags) {
$computerobj = Get-ADComputer $Notag -Properties memberof
$computerobj.memberof | ? {$_ -match '^CN=APP.*'} `
| % {get-adgroup $_ -Properties name, description} | `
% {$computerobj.Name + "|" + $_.name + "|" + $_.description `
| Out-File $groupExport -Append}
}
I see at least one issue here
$compImports = Get-Content "C:\Temp\temp\input.txt"
...
$PCs = Get-Content $compImports
You are calling Get-Content twice which would generate the error you are seeing most likely.
Could be simplified as
$PCs = Get-Content "C:\Temp\temp\input.txt"
Your other error should go away as a result since $PCs should contain real data at that point.

Powershell filter files by SQL Server result set and copy

I am executing a query in SQL Server and returning a single column result set. I need to loop through the result set and find file names matching the record from the result set. Part of the file name is a sequence number. I need to sort the files in ascending order, select the first file, and then copy only that file to a subdirectory. The records in the result set look like this:
MEMBERS.net MEMBERS_COMMENTS1.net
MEMBERS_COMMENTS2.net
MEMBERS_LANGUAGE.net
MEMBERS_COVER_OHC.net
MEMBERS_PROBLEM_LIST.net
The file names have this kind of structure:
00_1914330_MEMBERS.net
Can someone tell me why this does not achieve my end result?
add-pssnapin sqlservercmdletsnapin100
add-pssnapin sqlserverprovidersnapin100
cd SQLSERVER:\SQL\LOCALHOST\DEFAULT\Databases\SYSDB\Tables\dbo.STG0_EXPORT_JOBS
$ds = Invoke-Sqlcmd -ServerInstance 'LOCALHOST' -Query "SELECT CASE WHEN SUBSTRING([EXPORT_NAME],1,3) = 'MHC' THEN SUBSTRING([EXPORT_NAME],5,(LEN([EXPORT_NAME])))+'.net' ELSE [EXPORT_NAME]+'.net' END AS export FROM [SYSDB].[dbo].[STG0_EXPORT_JOBS] WHERE [JOB_NAME] = 'MHC_STG0_MEMBERS'"
foreach ($files in $ds) {
$oldestfile = Get-ChildItem C:\Scripts |
where{!$_.PSIsContainer -and $_.Name.EndsWith("$($files.export)")} |
sort-object -property name | select-object -first 1 Name |
Copy-Item "C:\Scripts\" + $oldestfile.substring(7,$oldestfile.length - 8) `
C:\Scripts\MEMBERS
}
Here is what I get when I run this:
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
PS H:> C:\powershell_MoveKoreFiles.ps1
Unexpected token 'in' in expression or statement.
At C:\powershell_MoveKoreFiles.ps1:1 char:472
+ add-pssnapin sqlserverprovidersnapin100 add-pssnapin sqlservercmdletsnapin100
Set-Location SQLSERVER:\SQL\LOCALHOST\DEFAULT\Databases\SYSDB\Tables\dbo.STG0_
EXPORT_JOBS $ds=Invoke-Sqlcmd -Query "SELECT CASE WHEN SUBSTRING([EXPORT_NAME],
1,3) = 'MHC' THEN SUBSTRING([EXPORT_NAME],5,(LEN([EXPORT_NAME])))+'.net' ELSE [
EXPORT_NAME]+'.net' END AS export FROM [SYSDB].[dbo].[STG0_EXPORT_JOBS] WHERE [
JOB_NAME] = 'MHC_STG0_MEMBERS'" -ServerInstance "LOCALHOST" foreach ($files in
<<<< $ds){$oldestfile = Get-ChildItem C:\Scripts|where{!$.PSIsContainer -and
$.Name.EndsWith("$($files.export)")}|sort-object -property name -descending|se
lect-object -first 1 Name|Copy-Item -path "C:\Scripts\"+$oldestfile.substring(7
,$oldestfile.length - 8) -destination C:\Scripts\MEMBERS}
+ CategoryInfo : ParserError: (in:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
PS H:>
I think there might be one too many pipes in the script. Remove the one after the Select -first 1 Name e.g.:
Add-PSSnapin sqlservercmdletsnapin100
Add-PSSnapin sqlserverprovidersnapin100
cd SQLSERVER:\SQL\LOCALHOST\DEFAULT\Databases\SYSDB\Tables\dbo.STG0_EXPORT_JOBS
$ds = Invoke-Sqlcmd -ServerInstance 'LOCALHOST' -Query "SELECT CASE WHEN " +
"SUBSTRING([EXPORT_NAME],1,3) = 'MHC' THEN " +
"SUBSTRING([EXPORT_NAME],5,(LEN([EXPORT_NAME])))+'.net' " +
"ELSE [EXPORT_NAME]+'.net' END AS export " +
"FROM [SYSDB].[dbo].[STG0_EXPORT_JOBS] " +
"WHERE [JOB_NAME] = 'MHC_STG0_MEMBERS'"
foreach ($files in $ds)
{
$oldestfile = Get-ChildItem C:\Scripts |
Where {!$_.PSIsContainer -and $_.Name.EndsWith("$($files.export)")} |
Sort name | Select Name -First 1
$oldName = "C:\Scripts\$($oldestfile.substring(7,$oldestfile.length - 8))"
Copy-Item $oldName C:\Scripts\MEMBERS
}