I need a script to change the IP address on all Windows 7 pro X64 PC.
If the first 2 match 192.168 then change
If IP already change then ignore and move onto next ip/PC.
Some PC will have more then 1 port.
I have try this which works but when you run it next time it keep adding the ip address.
$site = #{
Site1 = 2;
site2 = 3;
}
$site = $site.Values
$oldRange = "192.168."
foreach ($s in $site) {
$ipAddress = $oldRange + $s + ".*"
$printer = wmic path win32_tcpipprinterport get hostaddress
$printer = $printer.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
if ($printer) {
foreach ($p in $printer) {
$OldIP = $p
$OldIP2 = $OldIP -replace $oldRange, ""
$old = [bool]($OldIP -as [IPAddress])
if ($old) {
$NewIP = "172.15.$OldIP2"
$NewIP
wmic path win32_tcpipprinterport where "hostaddress = '$OldIP'" set hostaddress="$NewIP"
}
}
} else {
Write-Host "None Found"
}
}
This is what I have done.
if anyone has better solution then please let me know
Clear-Host
$site = #{
Site1=2;
Site2=3;
}
$site =$site.Values
$oldRange = "172.11."
foreach($s in $site)
{
$printer = wmic path win32_tcpipprinterport get hostaddress
$printer=$printer.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
if($printer)
{
foreach ($p in $printer)
{
$OldIP = $p
$OldIP2 = $OldIP -replace $oldRange, ""
$old = [bool]($OldIP -as [IPAddress])
if($old)
{
$sep = $OldIP.lastindexof(".")
$network = $OldIP.substring(0,$sep)
if("10.11."+$s -ne $network)
{
$NewIP = "10.11.$OldIP2"
$NewIP
wmic path win32_tcpipprinterport where "hostaddress = '$OldIP'" set hostaddress="$NewIP"
}else{
Write-Host "IP Already Changed"
}
}else
{
Write-Host "Not a IP address"
}
}
}else{
Write-Host "None Found"
}
}
Related
I'm new with powershell and i would like to use a loop to ping several Printers on my network.
My problem is : once i'm in the loop of pinging , i can't go out of the loop ...
I tried several things from google but without success ( start-stop , Timer ) . Does anybody have any idea?
Here is the code :
$BtnStartPingClicked = {
if ($LblFileSelectPing.Text -eq "*.txt") {
Add-Type -AssemblyName PresentationCore,PresentationFramework
$ButtonType = [System.Windows.MessageBoxButton]::OK
$MessageIcon = [System.Windows.MessageBoxImage]::Error
$MessageBody = "Please select a list of printer first"
$MessageTitle = "Error"
$Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)
Write-Host "Your choice is $Result"
}
else {
do {
$IPList = Get-Content ($LblFileSelectPing.Text)
$snmp = New-Object -ComObject olePrn.OleSNMP
$ping = New-Object System.Net.NetworkInformation.Ping
$i = 11
$j = 1
foreach ($Printer in $IPList) {
try {
$result = $ping.Send($Printer)
} catch {
$result = $null
}
if ($result.Status -eq 'Success') {
$((Get-Variable -name ("GBMachine"+$j+"Ping")).value).Visible = $True
$j++
test-Connection -ComputerName $Printer -Count 1 -Quiet
$printerip = $result.Address.ToString()
# OPEN SNMP CONNECTION TO PRINTER
$snmp.open($Printer, 'public', 2, 3000)
# MODEL
try {
$model = $snmp.Get('.1.3.6.1.2.1.25.3.2.1.3.1')
} catch {
$model = $null
}
# Serial
try {
$serial = $snmp.Get('.1.3.6.1.4.1.1602.1.2.1.8.1.3.1.1').toupper()
} catch {
$Dns = $null
}
# progress
$TBMonitoringPing.SelectionColor = "green"
$TBMonitoringPing.AppendText("$Printer is Pinging")
$TBMonitoringPing.AppendText("`n")
$mac = (arp -a $Printer | Select-String '([0-9a-f]{2}-){5}[0-9a-f]{2}').Matches.Value
# OPEN SNMP CONNECTION TO PRINTER
$((Get-Variable -name ('LblMach' + $i)).value).Text = "IP : $Printerip"
$i++
$((Get-Variable -name ('LblMach' + $i)).value).Text = "Model : $Model"
$i++
$((Get-Variable -name ('LblMach' + $i)).value).Text = "MAC : $mac"
$i++
$((Get-Variable -name ('LblMach' + $i)).value).Text = "Serial : $serial"
$TBAnswerMachine.AppendText("$Model")
$TBAnswerMachine.AppendText("`n")
$TBAnswerMachine.AppendText("$Printer - $Serial")
$TBAnswerMachine.AppendText("`n")
$TBAnswerMachine.AppendText("$Mac")
$TBAnswerMachine.AppendText("`n")
$TBAnswerMachine.AppendText("`n")
Get-Content ($LblFileSelectPing.Text) | Where-Object {$_ -notmatch $Printer} | Set-Content ("C:\_canonsoftware\out.txt")
$i = $i+7
$snmp.Close()
Start-Sleep -milliseconds 1000 # Take a breather!
}
else {
$TBMonitoringPing.selectioncolor = "red"
$TBMonitoringPing.AppendText("$Printer not pinging")
$TBMonitoringPing.AppendText("`n")
Start-Sleep -milliseconds 1000 # Take a breather!
}
}
$LblFileSelectPing.Text = "C:\_canonsoftware\out.txt"
} until($infinity)
}
}
thanks for your answers...
1 - part of my object are indeed not declared in the code because they are in my other PS1 file....
2 - I do a do until infinity because i don't want to stop the code before i decide it...
3 - I didn't explain my problem correctly ( excuse my poor english ) ... i would like to be able to go out of the loop do until at the moment i click on a stop button ... but apprently the windows doens't respond while in the loop ... i have to stop the script with powershell ... which is annoying because i'd like to make an executable with it ... and not have to go out of my program ...
thank you for your ideas
So I am trying to Purge IPs from tool that we use. Before I can purge the assets we need to make sure the host is not pingable and not in DNS. I am new to PS and cant seem to wrap my head around on doing this. Any help is greatly appreciated. I have been doing this as a manual process by pinging the list of IPs and hostnames and doing a nslookup in cmd prompt before selecting the IPs that are needing to be removed. I have about 13k IPs left to do.
Update:
I want to implement this portion into it. Where In cell A it will have the IP
cell B will let me know if it is up or down. And Cell D will let me know if it is DNS aswell. Below is the script I got for pinging and checking if up or down and checking AD to see if the hostname is still in AD. I want it similar to this.. Please excuse my english
$path = ".\results.xls"
$objExcel = new-object -comobject excel.application
if (Test-Path $path)
{
$objWorkbook = $objExcel.WorkBooks.Open($path)
$objWorksheet = $objWorkbook.Worksheets.Item(1)
}
else {
$objWorkbook = $objExcel.Workbooks.Add()
$objWorksheet = $objWorkbook.Worksheets.Item(1)
}
$objExcel.Visible = $True
#########Add Header####
$objWorksheet.Cells.Item(1, 1) = "HostName"
$objWorksheet.Cells.Item(1, 2) = "Result"
$objWorksheet.Cells.Item(1, 3) = "MachineIP"
$objWorksheet.Cells.Item(1, 4) = "Active Directory"
$machines = Get-Content .\machinelist.txt
$row=2
$machines | foreach-object{
$ping = $null
$iname = $null
$machine = $_
$ping = Test-Connection $machine -Count 1 -ea silentlycontinue
$checkAD = try {$comp = Get-ADComputer -Identity $machine -ErrorAction
Stop
if ($comp){"Yes"}else{throw}
}
catch {"No"}
$objWorksheet.Cells.Item($row,4) = $checkAD
if($ping){
$objWorksheet.Cells.Item($row,1) = $machine
$objWorksheet.Cells.Item($row,2) = "UP"
$iname = $ping.IPV4Address.IPAddressToString
$objWorksheet.Cells.Item($row,3) = $iname
$row++}
else {
$objWorksheet.Cells.Item($row,1) = $machine
$objWorksheet.Cells.Item($row,2) = "DOWN"
$row++}
}
Here's a start, using Test-Connection and Resolve-DnsName, assuming you have a list of hosts' IP and name separated by a space, with a carriage return between each host:
$Assets = #"
127.0.0.1 localhost
255.255.255.255 fakehost
"#
$FailedPing = #()
$NoDNS = #()
$Assets -split "`r" | %{
$ipaddress = ($_.split(' ')[0]).trim()
$hostName = ($_.split(' ')[1]).trim()
Write-Host "IP: $ipaddress HOST: $hostName "
Try {
Test-Connection -ComputerName $ipaddress -Count 2 -ErrorAction Stop | Out-Null
}Catch {
$FailedPing += [pscustomobject]#{IP=$ipaddress; HostName = $hostName}
}
Try {
Resolve-DnsName -Name $hostName -ErrorAction Stop | Out-Null
}Catch {
$NoDNS += [pscustomobject]#{HostName = $hostName;Problem = $Error[0].Exception}
}
}
$FailedPing | ft
$NoDNS | ft
Right now the below script imports info from a CSV file then outputs in a CSV file the computer name, expectedIP, Status, GoodIP, dnsName. This is all through custom PS object.
I am currently trying to get an output known as actual IP. I am not quite sure how to pull the IP via the ping function that pings the host name. For instance if the hostname that is being pinged check the IP and returns true or false. How could it output what the actual IP of the server is instead of outputting true or false?
Here is the script:
$compinfo = import-csv .\compinfo.csv
$lookupData = foreach ($comp in $cominfo) {
$nslkup = [System.Net.DNS]::GetHostEntry($comp.hname)
$ping = (Test-Connection -ComputerName $comp.hname -Count 1 -ErrorAction SilentlyContinue)
if ($ping) {
$status = "up"
} else {
$status = "down"
}
if ($nslkup.AddressList.IPAddressToString -eq $comp.ip) {
$ipgood = $true
} else {
$ipgood = $false
}
[PSCustomObject]#{
computerName = $comp.hname
expectedIp = $comp.ip
status = $status
goodIp = $ipgood
dnsName = $nslkup.hostname
}
}
$lookupData | Export-Csv .\lookups.csv -NoTypeInformation
I appreciate everyone that commented on this. I figured it out. Here is the correct code for anyone else that has this issue in the future.
$compinfo = import-csv .\compinfo.csv
$lookupData = foreach($comp in $compinfo)
{
$nslkup = [System.Net.DNS]::GetHostEntry($comp.hname)
$ping = (Test-Connection -ComputerName $comp.hname -Count 1 -ErrorAction SilentlyContinue)
if($ping)
{
$status = "up"
}
else
{
$status = "down"
}
if($nslkup.AddressList.IPAddressToString -eq $comp.ip)
{
$ipgood = $true
}
else
{
$ipgood = $nslkup.AddressList.IPAddressToString
}
[pscustomobject]#{
computerName = $comp.hname
expectedIp = $comp.ip
status = $status
goodIp = $ipgood
dnsName = $nslkup.hostname
}
}
$lookupData | export-csv .\lookups.csv -NoTypeInformation
Notice I replaced $False with $nslkup.AddressList.IPAddressToString
I am trying to create an script to get the certificate expiry date for an websites remotely for multiple servers. I have an script which is working for single server (Need to login into server and doing execution), I need to run this remotely for multiple servers. How can i modify this script to execute for multiple servers remotely. Please advice.
$servers = get-content D:\Certificate.txt
$DaysToExpiration = 60 #change this once it's working
$expirationDate = (Get-Date).AddDays($DaysToExpiration)
foreach ($server in $servers)
{
$sites = Get-Website | ? { $_.State -eq "Started" } | % { $_.Name }
$certs = Get-ChildItem IIS:SSLBindings | ? {
$sites -contains $_.Sites.Value
} | % { $_.Thumbprint }
Get-ChildItem CERT:LocalMachine/My | ? {
$certs -contains $_.Thumbprint -and $_.NotAfter -lt $expirationDate
}
}
Inspired by https://iamoffthebus.wordpress.com/2014/02/04/powershell-to-get-remote-websites-ssl-certificate-expiration/ I use following script:
$minimumCertAgeDays = 60
$timeoutMilliseconds = 10000
$urls = get-content .\check-urls.txt
#disabling the cert validation check. This is what makes this whole thing work with invalid certs...
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
foreach ($url in $urls)
{
Write-Host Checking $url -f Green
$req = [Net.HttpWebRequest]::Create($url)
$req.Timeout = $timeoutMilliseconds
$req.AllowAutoRedirect = $false
try {$req.GetResponse() |Out-Null} catch {Write-Host Exception while checking URL $url`: $_ -f Red}
$certExpiresOnString = $req.ServicePoint.Certificate.GetExpirationDateString()
#Write-Host "Certificate expires on (string): $certExpiresOnString"
[datetime]$expiration = [System.DateTime]::Parse($req.ServicePoint.Certificate.GetExpirationDateString())
#Write-Host "Certificate expires on (datetime): $expiration"
[int]$certExpiresIn = ($expiration - $(get-date)).Days
$certName = $req.ServicePoint.Certificate.GetName()
$certPublicKeyString = $req.ServicePoint.Certificate.GetPublicKeyString()
$certSerialNumber = $req.ServicePoint.Certificate.GetSerialNumberString()
$certThumbprint = $req.ServicePoint.Certificate.GetCertHashString()
$certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDateString()
$certIssuer = $req.ServicePoint.Certificate.GetIssuerName()
if ($certExpiresIn -gt $minimumCertAgeDays)
{
Write-Host Cert for site $url expires in $certExpiresIn days [on $expiration] -f Green
}
else
{
Write-Host WARNING: Cert for site $url expires in $certExpiresIn days [on $expiration] -f Red
Write-Host Threshold is $minimumCertAgeDays days. Check details:`nCert name: $certName -f Red
Write-Host Cert public key: $certPublicKeyString -f Red
Write-Host Cert serial number: $certSerialNumber`nCert thumbprint: $certThumbprint`nCert effective date: $certEffectiveDate`nCert issuer: $certIssuer -f Red
}
Write-Host
rv req
rv expiration
rv certExpiresIn
}
Alternatively, you might find this advanced script useful:
you can switch between report output as Text, Html or PSObject
use the script with urls (parameter array) or with input file for urls or with pipeline input
improved stability: correctly handle missing certificates on HTTP connections
just put the code into a file like Check-ExpiringSslCerts.ps1
Here the advanced script code:
[CmdletBinding(DefaultParametersetname="URLs in text file")]
Param(
[ValidateSet('Text','Html','PSObject')]
[string]$ReportType = 'Text',
[int]$MinimumCertAgeDays = 60,
[int]$TimeoutMilliseconds = 10000,
[parameter(Mandatory=$false,ParameterSetName = "URLs in text file")]
[string]$UrlsFile = '.\check-urls.txt',
[parameter(Mandatory=$false,ParameterSetName = "List of URLs",
ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$Urls
)
Begin
{
[string[]]$allUrls = #()
$returnData = #()
[bool]$ProcessedInputPipeLineByArrayItem = $false
function CheckUrl ([string]$url, [array]$returnData)
{
[string]$details = $null
if ($ReportType -eq "Html")
{
$stringHtmlEncoded = [System.Web.HttpUtility]::HtmlEncode($url)
Write-Host "<tr><td>$stringHtmlEncoded</td>"
}
if ($ReportType -eq "Text") { Write-Host Checking $url }
$req = [Net.HttpWebRequest]::Create($url)
$req.Timeout = $timeoutMilliseconds
$req.AllowAutoRedirect = $false
try
{
$req.GetResponse() |Out-Null
if ($req.ServicePoint.Certificate -eq $null) {$details = "No certificate in use for connection"}
}
catch
{
$details = "Exception while checking URL $url`: $_ "
}
if ($details -eq $null -or $details -eq "")
{
$certExpiresOnString = $req.ServicePoint.Certificate.GetExpirationDateString()
#Write-Host "Certificate expires on (string): $certExpiresOnString"
[datetime]$expiration = [System.DateTime]::Parse($req.ServicePoint.Certificate.GetExpirationDateString())
#Write-Host "Certificate expires on (datetime): $expiration"
[int]$certExpiresIn = ($expiration - $(get-date)).Days
$certName = $req.ServicePoint.Certificate.GetName()
$certPublicKeyString = $req.ServicePoint.Certificate.GetPublicKeyString()
$certSerialNumber = $req.ServicePoint.Certificate.GetSerialNumberString()
$certThumbprint = $req.ServicePoint.Certificate.GetCertHashString()
$certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDateString()
$certIssuer = $req.ServicePoint.Certificate.GetIssuerName()
if ($certExpiresIn -gt $minimumCertAgeDays)
{
if ($ReportType -eq "Html")
{
Write-Host "<td>OKAY</td><td>$certExpiresIn</td><td>$expiration</td><td> </td></tr>"
}
if ($ReportType -eq "Text")
{
Write-Host OKAY: Cert for site $url expires in $certExpiresIn days [on $expiration] -f Green
}
if ($ReportType -eq "PSObject")
{
$returnData += new-object psobject -property #{Url = $url; CheckResult = "OKAY"; CertExpiresInDays = [int]$certExpiresIn; ExpirationOn = [datetime]$expiration; Details = [string]$null}
}
}
else
{
$details = ""
$details += "Cert for site $url expires in $certExpiresIn days [on $expiration]`n"
$details += "Threshold is $minimumCertAgeDays days. Check details:`n"
$details += "Cert name: $certName`n"
$details += "Cert public key: $certPublicKeyString`n"
$details += "Cert serial number: $certSerialNumber`n"
$details += "Cert thumbprint: $certThumbprint`n"
$details += "Cert effective date: $certEffectiveDate`n"
$details += "Cert issuer: $certIssuer"
if ($ReportType -eq "Html")
{
Write-Host "<td>WARNING</td><td>$certExpiresIn</td><td>$expiration</td>"
$stringHtmlEncoded = [System.Web.HttpUtility]::HtmlEncode($details) -replace "`n", "<br />"
Write-Host "<tr><td>$stringHtmlEncoded</td></tr>"
}
if ($ReportType -eq "Text")
{
Write-Host WARNING: $details -f Red
}
if ($ReportType -eq "PSObject")
{
$returnData += new-object psobject -property #{Url = $url; CheckResult = "WARNING"; CertExpiresInDays = [int]$certExpiresIn; ExpirationOn = [datetime]$expiration; Details = $details}
}
rv expiration
rv certExpiresIn
}
}
else
{
if ($ReportType -eq "Html")
{
Write-Host "<td>ERROR</td><td>N/A</td><td>N/A</td>"
$stringHtmlEncoded = [System.Web.HttpUtility]::HtmlEncode($details) -replace "`n", "<br />"
Write-Host "<tr><td>$stringHtmlEncoded</td></tr>"
}
if ($ReportType -eq "Text")
{
Write-Host ERROR: $details -f Red
}
if ($ReportType -eq "PSObject")
{
$returnData += new-object psobject -property #{Url = $url; CheckResult = "ERROR"; CertExpiresInDays = $null; ExpirationOn = $null; Details = $details}
}
}
if ($ReportType -eq "Text") { Write-Host }
rv req
return $returnData
}
#disabling the cert validation check. This is what makes this whole thing work with invalid certs...
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
if ($ReportType -eq "Html")
{
Write-Host "<table><tr><th>URL</th><th>Check result</th><th>Expires in days</th><th>Expires on</th><th>Details</th></tr>"
Add-Type -AssemblyName System.Web
}
}
Process
{
if ($_ -ne $null)
{
CheckUrl $_ $returnData
$ProcessedInputPipeLineByArrayItem = $true
}
}
End
{
if ($ProcessedInputPipeLineByArrayItem -eq $false)
{
if ($Urls -eq $null)
{
$allUrls = get-content $UrlsFile
}
else
{
$allUrls = $Urls
}
foreach ($url in $allUrls)
{
$returnData = CheckUrl $url $returnData
}
}
if ($ReportType -eq "Html") { Write-Host "</table>" }
if ($ReportType -eq "PSObject") { return $returnData }
}
Output might look like e.g.:
"http://www.doma.com", "https://www.domb.com" | .\Check-ExpiringSslCerts.ps1 -ReportType PSObject | ft
Url ExpirationOn CertExpiresInDays CheckResult Details
--- ------------ ----------------- ----------- -------
http://www.doma.com ERROR No certificate in use for connection
https://www.domb.com 18.11.2017 09:33:00 87 OKAY
Put the whole code you've wrote in a script-block, in order to do so, just add at the beginning this code:
$sb = {
and at the bottom of your code add:
}
Once you have this script-block, you can run this script on the servers remotely using these commands:
$cred = Get-Credential
$servers = get-content D:\Certificate.txt
Invoke-Command -Credential $cred -ComputerName $servers -ScriptBlock $SB
Hope it helped!
Your code snippets are helpful but they will throw an error on HTTP errors -- that is the nature of the underlying .NET HttpWebRequest object to panic on everything that's not code 200.
So, if you're testing, say, API endpoints that only accept POST HTTP verb, your script will fail as it will get a 405 error message. Alternatively, if your URL returns HTTP 404, your script will fail as well. Luckily, you can catch layer 7 errors and capture the required info anyway just patch your code in this manner:
try {$req.GetResponse() | Out-Null } catch {
if ($_.Exception.InnerException.Status -eq 'ProtocolError') {
# saving the info anyway since this is a L7 error, e.g.:
$certExpiresOnString = $req.ServicePoint.Certificate.GetExpirationDateString()
[datetime]$expiration [System.DateTime]::Parse($req.ServicePoint.Certificate.GetExpirationDateString())
$certIssuer = $req.ServicePoint.Certificate.GetIssuerName() # ...
} else {
# this is a real error - timeout, DNS failure etc
Write-Host "$url, $_" -ForegroundColor Red
Continue
}
}
Taken mostly from https://gist.github.com/jstangroome/5945820, although with some changes. The following will obtain the certificate. $certificate.NotBefore and $certificate.NotAfter will then need to be checked.
function GetCertificate([string]$domain, [Int16]$port) {
$certificate = $null
$TcpClient = New-Object -TypeName System.Net.Sockets.TcpClient
$TcpClient.ReceiveTimeout = 1000
$TcpClient.SendTimeout = 1000
try {
$TcpClient.Connect($domain, $port)
$TcpStream = $TcpClient.GetStream()
$Callback = { param($sender, $cert, $chain, $errors) return $true }
$SslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList #($TcpStream, $true, $Callback)
try {
$SslStream.AuthenticateAsClient($domain)
$certificate = $SslStream.RemoteCertificate
}
finally {
$SslStream.Dispose()
}
}
finally {
$TcpClient.Dispose()
}
if ($certificate) {
if ($certificate -isnot [System.Security.Cryptography.X509Certificates.X509Certificate2]) {
$certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $certificate
}
}
return $certificate
}
I am trying to modify a PS script from online resource:
Trap {"Error: $_"; Break;}
$D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"
$Searcher.Filter = "(objectCategory=computer)"
$Searcher.PropertiesToLoad.Add("samAccountName") > $Null
$Searcher.PropertiesToLoad.Add("lastLogon") > $Null
# Create hash table of users and their last logon dates.
$arrComp = #{}
# Enumerate all Domain Controllers.
ForEach ($DC In $D.DomainControllers)
{
$Server = $DC.Name
$Searcher.SearchRoot = "LDAP://$Server/" + $Domain.distinguishedName
$Results = $Searcher.FindAll()
ForEach ($Result In $Results)
{
$DN = $Result.Properties.Item("samAccountName")
$LL = $Result.Properties.Item("lastLogon")
If ($LL.Count -eq 0)
{
$Last = [DateTime]0
}
Else
{
$Last = [DateTime]$LL.Item(0)
}
If ($Last -eq 0)
{
$LastLogon = $Last.AddYears(1600)
}
Else
{
$LastLogon = $Last.AddYears(1600).ToLocalTime()
}
If ($arrComp.ContainsKey("$DN"))
{
If ($LastLogon -gt $arrComp["$DN"])
{
$arrComp["$DN"] = $LastLogon
}
}
Else
{
$arrComp.Add("$DN", $LastLogon)
}
}
}
Script above give me the computername & its' last logon date, however the computernames are having "$" at the end. I would like to trim the "$" in order for me to use it remove the computer from AD later. However my script is not working.
$Compdollar = $arrComp.getEnumerator() | Select-Object Key | out-string
$AllComp = #()
Foreach ($inactD in $Compdollar) {
$AllComp += $inactD.Trim("$")
}
$Allcomp
The output is still computer name with "$", can anyone tells me why it wasn't trimmed?
Don't use double quotes with a $ as it is treated like a variable. Use single quotes instead.
$AllComp += $inactD.Trim('$')
Or use the backtick to escape the dollar sign.
$AllComp += $inactD.Trim("`$")