Dahua API Authentication From PowerShell

Swampledge

Getting comfortable
Apr 9, 2021
218
474
Connecticut
I have a couple year old 5241 Z12 serving as a license plate camera. It periodically goes out of focus after the day/night configuration change triggered via Blue Iris. I am attempting to write a PowerShell script to query the camera’s focus setting and notify me if the value is incorrect.

I can successfully query the camera using a web browser and the calll, and have it return the status. When I insert the exact same (and I know there’s no typos because I tested it using copy/paste) URL into the PowerShell Invoke-WebRequest call, I get a 401 Unauthorized error.

I had assumed the camera’s server would not know the difference between the request coming from a browser or PowerShell, but apparently there is a difference. Any suggestions?
 
You might have to use the curl command to get it to work.

Many here use Task Manager to periodically send the focus number to the camera.
 
  • Like
Reactions: Swampledge
….Still no joy, despite trying @wittaj ‘s suggestion. It appears the problem lies within how PowerShell sends the request to the camera. I have progressed to where PowerShell will bring up its own authentication dialog, and, after I respond to it, then it will return a proper response object. I’m a newbie to PowerShell, so that doesn’t help. I think I just need to find how to properly structure the “username:password” credentials.
 
I have noticed that sometimes it doesn't like characters in the user/PW. Probably not your issue, but worth a shot if you do.
 
can I see the code you are using? For one of my Dahua cameras. I will try your script on my system and see if there is something I can see that might be missing? easy as times to forget something in the code or something easy to over look..

status.Focus=0.946512
status.FocusMotorSteps=3010
status.LenAdjustStatus=0
status.Status=Normal
status.Zoom=0.584642
status.ZoomMotorSteps=2292
 
I have tested and written my own and having Auth issues my self some of it is because of my password type.. However even trying to run the command in curl I get not auth so I am still working something out lol. Or trying to.. .
 
so I did in fact work something out

However because of the way the camera is expecting things to work I had to make with curl as well.. Here is my output...

PS /home/revo2maxx/Desktop> pwsh -File Check-CameraFocus13.ps1
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 150 100 150 0 0 2830 0 --:--:-- --:--:-- --:--:-- 2830
Focus Status: status.Focus=0.946512 status.FocusMotorSteps=3010 status.LenAdjustStatus=0 status.Status=Normal status.Zoom=0.584642 status.ZoomMotorSteps=2292
 
Here is the code I used, Maybe that info into what you are working with will get what you need figured out.. Hope it was helpful

Code:
$User = "admin"
$Password = "password"
$CameraIP = "10.0.0.65"
$URL = "http://$CameraIP/cgi-bin/devVideoInput.cgi?action=getFocusStatus"

# Use ${} for variable interpolation within the string
$CurlCommand = "curl --digest -u ${User}:${Password} $URL"
try {
    $Response = Invoke-Expression $CurlCommand
    Write-Host "Focus Status: $Response"
} catch {
    Write-Host "Failed to fetch focus status. Error: $_"
}
 
Last edited:
Thanks for the responses. Had some family visits, so had to put this aside for a spell. I’ll post up what I get working when I get back to it tomorrow.
 
I have gotten past my authentication hurdle. I used the following code:

$user="admin"
$password=ConvertTo-SecureString "mypassword" -AsPlainText -Force
$psCred=New-Object PSCredential -ArgumentList ($user,$password)
Invoke-WebRequest -Credential $psCred

This returns an object which i can now parse to check the focus setting and take action.
@Revo2Maxx, thanks for your assistance. Your code did not work for me because PowerShell said the -u parameter was ambiguous. This led me down a variety of paths where I ended up upgrading my version of Powershell to Version 7 something from the original 5 something. One of the differences between these versions is that, in the earlier version, Curl is an alias for the Invoke-WebRequest cmdlet, while in later version it actually invokes curl.exe. I sidestepped that issue.
 
Last edited:
No need to apologize! My biggest challenge is being a newbie to PowerShell, so I need to learn everything from ground level in an unfamiliar environment. I had considered programming this in Python, but I haven’t coded in Python in about 8 years, so II’m rusty there. At some point I’ll have my whole script working and will share it, as clunky as it might become. :)
 
Trying PowerShell to display Dahua camera NTP settings.

The following URL works in FireFox.

Code:
http://admin:123456@192.168.55.76/cgi-bin/configManager.cgi?action=getConfig%26name=NTP

It returns the following data in the FF browser.

table.NTP.Address=192.168.55.11
table.NTP.Enable=true
table.NTP.Port=123
table.NTP.TimeZone=28
table.NTP.TimeZoneDesc=Alaska
table.NTP.UpdatePeriod=15

The reason for the script, is to check if each camera has the correct NTP settings. Examples would be to change the Time Zone from 29 to 28 with the daylight savings time change. Or to alter the Update Period for each camera to 15 minutes each in place of changing each camera individually by using a corresponding SET statement.

Attempting PowerShell (see below) for the same GET output NTP scenario. So far the script displays an error. "The remote server returned an error: (401) Unauthorized."

Code:
# User credentials
$username = "admin"
$password = "123456"

# Encode credentials for Basic Authorization
$authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${username}:${password}"))

# Camera URL
# %26 used in place of an ampersand
$uri = "http://192.168.55.76/cgi-bin/configManager.cgi?action=getConfig%26name=NTP"

# Headers for the request
$headers = @{
    "X-Requested-With" = "powershell"
    "Authorization"    = "Basic $authInfo"
}

# Fetch NTP time data from the camera
try {
    [xml]$results = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
    Write-Host "NTP time data fetched successfully."
} catch {
    Write-Host "Failed to fetch NTP time data: $_"
}

# Output file path
$dest = "C:\test\pstest.txt"

# Write NTP time data to the file
try {
    Invoke-RestMethod -Uri $uri -Headers $headers -OutFile $dest
    Write-Host "NTP time data written to $dest successfully."
} catch {
    Write-Host "Failed to write NTP time data to file: $_"
}

This script was generated using the GetHub AI machine.

May try some other variations with GetHub AI to see what is possible. Any script change suggestions are invited. Or perhaps Power Shell is not the correct program to use and a switch to Curl would be simpler.
 
Trying PowerShell to display Dahua camera NTP settings.

The following URL works in FireFox.

Code:
http://admin:123456@192.168.55.76/cgi-bin/configManager.cgi?action=getConfig%26name=NTP

It returns the following data in the FF browser.

table.NTP.Address=192.168.55.11
table.NTP.Enable=true
table.NTP.Port=123
table.NTP.TimeZone=28
table.NTP.TimeZoneDesc=Alaska
table.NTP.UpdatePeriod=15

The reason for the script, is to check if each camera has the correct NTP settings. Examples would be to change the Time Zone from 29 to 28 with the daylight savings time change. Or to alter the Update Period for each camera to 15 minutes each in place of changing each camera individually by using a corresponding SET statement.

Attempting PowerShell (see below) for the same GET output NTP scenario. So far the script displays an error. "The remote server returned an error: (401) Unauthorized."

Code:
# User credentials
$username = "admin"
$password = "123456"

# Encode credentials for Basic Authorization
$authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${username}:${password}"))

# Camera URL
# %26 used in place of an ampersand
$uri = "http://192.168.55.76/cgi-bin/configManager.cgi?action=getConfig%26name=NTP"

# Headers for the request
$headers = @{
    "X-Requested-With" = "powershell"
    "Authorization"    = "Basic $authInfo"
}

# Fetch NTP time data from the camera
try {
    [xml]$results = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
    Write-Host "NTP time data fetched successfully."
} catch {
    Write-Host "Failed to fetch NTP time data: $_"
}

# Output file path
$dest = "C:\test\pstest.txt"

# Write NTP time data to the file
try {
    Invoke-RestMethod -Uri $uri -Headers $headers -OutFile $dest
    Write-Host "NTP time data written to $dest successfully."
} catch {
    Write-Host "Failed to write NTP time data to file: $_"
}

This script was generated using the GetHub AI machine.

May try some other variations with GetHub AI to see what is possible. Any script change suggestions are invited. Or perhaps Power Shell is not the correct program to use and a switch to Curl would be simpler.
Did you try using the simple code I posted? Just substitute your username, password, etc. PowerShell seemed to need the PSCredential object and the SecureString form of the password to allow the login to the camera.
 
Updated PS from version 5 to 7.50.

It almost works but has an issue with unencrypted connections.

Code:
PS C:\> $user="admin"
>> $password=ConvertTo-SecureString "password" -AsPlainText -Force
>> $psCred=New-Object PSCredential -ArgumentList ($user,$password)
>> Invoke-WebRequest http://192.168.55.20/cgi-bin/devVideoInput.cgi?action=getFocusStatus -Credential $psCred

Line |
   4 |  Invoke-WebRequest http://192.168.55.20/cgi-bin/devVideoInput.cgi?acti …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The cmdlet cannot protect plain text secrets sent over unencrypted connections. To suppress this warning and send plain text secrets over unencrypted networks, reissue the command specifying the AllowUnencryptedAuthentication parameter.
 
Try adding the -AllowUnencryptedAuthentication parameter and try it. After all, the command is staying within your LAN, so it shouldn’t be an issue. Not sure why I don’t get that warning, though. Probably some setup thing in PowerShell.