I'm trying to create PowerShell script to get the NIC speed of remote hosts, and output the end result to a txt file.
So far, this is what I've got:
Hostname
Get-NetAdapter | SELECT LinkSpeed
Out-File C:\CheckNIC-Speed\checknic.txt
That's a script for the local computer, but it also won't output the results to the txt, instead it will just create an empty file.
Now, I also need to run it on multiple remote hosts and get the output to the same file.
Thanks.
("Server1","Server2","Server3") | Foreach {
Invoke-Command -ComputerName $_ -ScriptBlock {
[PSCustomObject]#{
LinkSpeed = (Get-NetAdapter).LinkSpeed -join " & "
HostName = $env:COMPUTERNAME
}
}
} | Out-File "C:\File.txt"
This should retrieve info for any of the servers listed within the brackets, you can also import from a list.
look up Invoke-Command Help if you need to do this kind of thing.
You can use wmi-object for the same:
get-wmiobject win32_networkadapter -ComputerName Server01,Server02,Server03 | select name,speed, pscomputername
Related
I'm brand new to PS scripting, so bear with me :)
I'm trying to create a PS script that will write the Win10 activation code to a file then copy that file to a central repo to then manually activate.
I'm creating a PS script and trying to run
cscript.exe c:\windows\system32\slmgr.vbs -dti >
$SourceDir\$env:computername.txt
$SourceDir = \\computer01\c$\temp
I need to run it from one computer, remotely connecting to every computer on the network, creating the computername.txt file then copying that file back to a central repository for all the files.
What I have so far:
$s1=New-PSSession -ComputerName computer01 -Credential $AdminCred
Test-Connection -ComputerName computer01
$id='\\computer01\windows\system32'
$SourceDir='\\computer01\c$\temp'
md $SourceDir
$GetActID=cscript.exe $id\slmgr.vbs -dti >
$SourceDir\$env:computername.txt
Invoke-Command -Session $s1 -ScriptBlock { $Using:GetActID }
Then I call a batch file that copies the computername.txt file from the computer01 over to a repository where they are going to sit.
I FINALLY got it working correctly except for the name of the file isn't naming it to the computer01, it's naming it with the hostname of the computer I'm running it from, therefore the filenames are identical. I had the naming piece working, but I had to change the way I was remoting into the computer and now it's not naming correctly.
Any idea on how I could get it to name the file to be related to the remote computer?
**I'm still working on the whole piece of the puzzle where it goes back to an excel sheet pulled from AD and pulls the host names from that sheet to connect to each machine, I believe I'll be adding a ForEach syntax in there somehow for that.
Although not sure how you are getting the list of "every computer on the network", chances are you are doing this using
# get a list of all AD computers (their names only)
$computers = (Get-ADComputer -Filter *).Name
Then I think you don't need to have every computer save the file on its own disk and later copy these files to a central share.
Instead, just capture the info in a variable and after the loop write the file to the central share as structured CSV file combining all computernames and install id's so you can open in Excel.
Using the array of computernames from above, iterate through them
$result = $computers | ForEach-Object {
# test if the computer can be reached
if (Test-Connection -ComputerName $_ -Count 1 -Quiet) {
$installId = Invoke-Command -ComputerName $_ -ScriptBlock {
cscript.exe //nologo "$env:SystemRoot\System32\slmgr.vbs" -dti
}
# $installId is returned as array !
# output an object with two properties
[PsCustomObject]#{
Computer = $_
InstallId = $installId[0] -replace '\D' # remove everything non-numeric
}
}
else {
Write-Warning "Computer $_ is not responding"
}
}
# now you can display the result on screen
$result | Format-Table -AutoSize
# or by means of the GridView if you prefer
$result | Out-GridView -Title 'Computer InstallIds'
# and save the results in your central share as structured CSV file
$result | Export-Csv -Path '\\server\share\restofpath\ComputerInstallIds.csv' -NoTypeInformation
You may have to append -Credential $adminCreds to the Invoke-Command call to make sure you have permissions to have each machine run that piece of code in the scriptblock. The easiest way of obtaining that credential is to start off with $adminCreds = Get-Credential -Message "Please enter administrator credentials"
Trying to get list of all machines in a Domain with a certain service
tried via all posts in here, helped per one machine, but if i use a text file with multiple machines, it failes
$computers = Get-Content c:\script\computers.txt
$service = "*crystal*"
foreach ($computer in $computers) {
$servicestatus = Get-Service -ComputerName $computer -Name $service
}
$Data = $servicestatus | Select-Object Name,Machinename | Format-Table -AutoSize
Write($Data) | Out-File c:\script\output.txt -Append
Expected list of machines with service in table, instead got error:
This operation might require other privileges
same script, but with a direct machine name, works like a charm.
Any clue what is wrong?
Why not use:
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Service -Name *crystal*}
Eventually you may store the result from invoke into a variable and work with it.
The benefit of using Invoke-Command, insted of foreach is that Invoke works in parallel, while foreach is serial ...
Hope it helps!
Best regards,
Ivan
I've tried a variety of iterations of this and gotten a range of errors. I'm trying to get a a list of installed drivers off from a list of computers. None of the ways I've tried in PowerShell have piped the information into a csv. Here's the current iteration of the script.
#Load Active Directory
Import-Module activedirectory
#Load list of computers
$results = #()
$Computer = Get-Content -path 'C:\ScriptResources\computers.txt'
#Check each computer in the list
foreach($ComputerName in $Computer)
{
$results += Get-ADComputer -Filter " Name -Like '*$ComputerName*' " | Get-PrinterDriver; Start-Sleep -milliseconds 500
}
#Export to CSV file
$results | export-csv 'C:\ScriptResults\InstalledPrinters.csv'
I've also used it with just the Get-Printer command and got the following error.
Get-Printer : No MSFT_Printer objects found with property 'Name' equal to 'Redacted'. Verify the value of the
property and retry.
Depending what I've fed the $Computer file I'll get different errors. I've also gotten the RPC server is unavailable and Error Spooler Service Not Running. I have domain wide privileges and I checked the print spooler service and it is running.
The reason I think this is odd is that I have .bat tool that I use that gets printer info from a singular host and I don't run into any issues. The reason I'm trying to put this in PowerShell is because 1) I want to do the whole domain and 2) PowerShell formats its outputs in a more useable fashion.
wmic /node:%ComputerIP% path win32_printer get deviceid, drivername, portname
Additionally, I've also tried the following in the $results function of the script
$results += Get-WmiObject -class Win32_printer -ComputerName name, systemName, shareName
This didn't give errors. What it did instead is that for each computer in the list of computers it checked the computer I was running the script from for its printers and output on each line which printers were installed on my computer.
I'm at a loss and any help would be appreciated. Thanks!
Just so this is closed out. Vivek's answer ended up working.
$results += Get-WmiObject -class Win32_printer -ComputerName $Computer | Select name, systemName, shareName
The RPC issue I was getting was that the list of computers were all turned off for some reason (remote site + different time zone + doing the testing during second shift). Normally, everything remains on though. So that was just an anomaly.
Thanks for the help!
I know I must be using these commands wrong but I can't seem to find a solution. I believe the issue is with my use of the invoke-command and out-file. I'm trying to check to see if a process is running on multiple remote machines and write their states back to a text file on the host system. Even if it wrote to the remote system I could work with that but I cant seem to get anything.
$MyDomain=’mydomain’
$MyClearTextUsername=’myusername’
$MyClearTextPassword=’mypassword’
$MyUsernameDomain=$MyDomain+’\’+$MyClearTextUsername
$SecurePassword=Convertto-SecureString –String $MyClearTextPassword
-AsPlainText –force
$MyCredentials=New-object System.Management.Automation.PSCredential
$MyUsernameDomain,$SecurePassword
$Servers = ( "server1","server2","server3")
$output = foreach ($Server in $Servers)
{
$Session = New-PSSession -ComputerName $Server -Credential $MyCredentials
Invoke-Command -Session $Session -ScriptBlock
{
Get-Service -Name service | select name, status, PSComputername, Runspaceid
} | Out-File -filepath 'c:\TEMP\check.txt'
}
Write-output $output | Out-File -filepath 'c:\TEMP\check.txt'
edit: I don't believe the last line is needed but I threw it in just to see if I could get anything out.
You are not capturing anything in $output because you are redirecting all of the output from your Invoke-Command to Out-File -filepath 'c:\TEMP\check.txt'. Get-Service doesn't return that much data, especially once's it's been deserialized when it returns from the remote session, so I wouldn't bother with the Select statement. Even if you do want to include the Select statement you are specifying PSComputerName which doesn't get added until the data comes back from the remote system, so you may want to move that Select to outside of the scriptblock and after the Invoke-Command in the pipeline. Plus, since you are outputting with Out-File your local file is being overwritten each time that call is made, so the first server's results are saved, then overwritten by the second server's results, then by the third server's results. After that, since $output has nothing (as all output was redirected to file), you are outputting an empty variable to the same file, effectively erasing the service state of the third server.
But this really all becomes a moot point if the script is run with the credentials that has access to the remote servers. You can specify one or more computer names to the Get-Service cmdlet, so this could become as simple as:
$Results = Get-Service Service -ComputerName 'Server1','Server2','Server3'
$Results | Select name, status, PSComputername, Runspaceid | Set-Content 'C:\TEMP\check.txt'
Just to make sure... you are looking for a service right? Not just a process? Because if it isn't a service you would need to use Get-Process instead of Get-Service.
If you want to output the data to the remote server you could do:
$output = foreach ($Server in $Servers)
{
$Session = New-PSSession -ComputerName $Server -Credential $MyCredentials
Invoke-Command -Session $Session -ScriptBlock
{
Get-Service -Name service | Tee-Object -FilePath C:\Temp\ServiceState.txt
} | select name, status, PSComputername, Runspaceid
}
$output | Out-File -filepath 'c:\TEMP\check.txt'
That should make a file in the C:\Temp folder on each server with the state of the service, as well as pass the information back to the local host, where it is passed to Select and stored in $output. At the end I output $output to file, just as you did.
I guess in the end you could just remove the Out-File call from within your loop, and it would probably do what you want it to.
I have this script that I am trying to run, that I hope will back up DNS zones. I am attempting to export this information into a csv file using the export-csv powershell cmdlet. Finally, I use use the dnscmd.exe command to export zones information into a text file and store them in the defined location.
# Get Name of the server with env variable
$DNSSERVER=get-content env:computername
#—Define folder where to store backup —–#
$BkfFolder=”c:\windows\system32\dns\backup”
#—Define file name where to store Dns Settings
$StrFile=Join-Path $BkfFolder “input.csv”
#—-Check if folder exists. if exists, delete contents–#
if (-not(test-path $BkfFolder)) {
new-item $BkfFolder -Type Directory | Out-Null
} else {
Remove-Item $BkfFolder”\*” -recurse
}
#—- GET DNS SETTINGS USING WMI OBJECT ——–#
#– Line wrapped should be only one line –#
$List = get-WmiObject -ComputerName $DNSSERVER
-Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone
#—-Export information into input.csv file —#
#– Line wrapped should be only one line –#
$list | Select Name,ZoneType,AllowUpdate,#{Name=”MasterServers”;Expression={$_.MasterServers}},
DsIntegrated | Export-csv $strFile -NoTypeInformation
#— Call Dnscmd.exe to export dns zones
$list | foreach {
$path=”backup\”+$_.name
$cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path
Invoke-Expression $cmd
}
# End of Script
#——————————————————————————————-#
When I run the script, I get the following message:
I am not exactly sure what this message is saying. I tried inputting my computer name, but that does not work either.
Any help is appreciated!
From line 2:
$DNSSERVER=get-content env:computername
should be:
$DNSSERVER = $Env:Computername
The error is in this line:
$List = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone
Make sure that it's on the same line instead of separate lines, It is requesting the class for the gwmi command, but since it is in another line it's not taking it. Because the class does exist in here so the issue should be in that particular line.
Another point it is looking for the DNS class so only would work if the windows servers have DNS feature or role installed on it.